C # - How can I make sure all my structures are initialized?

I am writing a C # application that will do extensive calculations. Everything goes around the basic structure - Value. It is basically double with some additional parameters (precision, etc.). It should be a structure, because too many of them will be created to distribute the heap. Now I need to make sure that they are all correctly initialized. I cannot declare an explicit default constructor, although I am provided with a default constructor that initializes everything with 0, which does not make sense in my domain.

And there is no way to deny instantiating without calling my constructor with parameters either ...?

I basically need this test:

[Test] public void HowDoesThisStructureInitializeByDefault() { Value v = new Value(); - if this did not compile - it would have been ok! Assert.AreEqual(0, v.Val); - passes Assert.AreEqual(-1, v.Accuracy); - fails } 

It would be normal to throw an exception if the constructor was not explicitly called and the structure is still available, but checking that it takes too much time all the time.

I'm almost losing hope now, please help!

+6
c # struct value-type
source share
5 answers

Why can't you define an explicit constructor? For this they are needed. Moreover, why do you think that “you cannot afford the allocation of the heap”? Heap allocation is very cheap in managed languages. How did you test this assumption that you cannot afford heap allocation, or is it really that heap allocation is more expensive in the first place?

(For a type consisting of "double and multiple parameters", I suspect you're in a size where the heap distribution is actually cheaper and more efficient)

In any case, you cannot prevent the user from invoking the default constructor for the value type if he so desires. All you can do is make sure that there is a better way to initialize the value, for example, a non-default constructor, or if you cannot create it for any reason, a function that creates and initializes your value type when called.

But, of course, you have no guarantee that people actually call him.

Edit: .NET heap allocation basically consists of a simple push push operation. This is a good thing about managed (and garbage collected) languages. Runtime substantially uses a large stack as a heap, so each allocation slightly increases the stack pointer (after checking that, of course, there is enough free memory). The garbage collector then takes care of memory compression when necessary.

Thus, heap allocation is very ridiculously cheap. Of course, the additional pressure in the GC can slow you down again (although, as far as I know, the time required to go through the GC depends only on the number of living objects, and not on those that should be GC'ed, therefore with countless "dead" objects may not be a big problem), but on the other hand, stack distribution is also not free. Value types are passed by value, so every time you pass your type as a parameter to a function or return it, a copy must be made. I don’t know how great your value is, but double is 8 bytes, and given that you have some additional parameters, I will take 32 bytes. It can be so large that the extra copying required by valuetypes makes it slower than if you used heap allocation. May be.

As you can see, there are advantages for both values ​​and reference types. I can’t say which one is faster in your case, but if I were you, I would very carefully make such assumptions. If possible, structure your code so that you can switch between the reference- and valuetype implementations and see which one works best. Alternatively, write smaller tests to try to predict how each will work on a large scale.

+4
source share

You cannot get rid of the default constructor (Jon Skeet, of course, answered why it is very good at Why can't I define a default constructor for a structure in .NET.? ), But you can create a factory class that allows you to define your own structural Values ​​with correctly initialized parameters. You can use unit tests with mock / verify to make sure that they use factory when creating new values ​​with your code. This will be the convention that you will need to apply, since the compiler will not apply it for you.

 public static class StructFactory { public static Value DefaultValue() { Value v = new Value(); v.Value = 0.0; v.Accuracy = 15; /* digits */ return v; } } ... Value v = StructFactory.DefaultValue(); 
+3
source share

Struct fields are initialized to zero (or zero, or generally by default (T)).

If you want the initial Accuracy value to be -1, you can implement the Accuracy property, so when the base field == 0, the property returns -1.

One possibility:

 struct Value { int _accuracyPlusOne; public int Accuracy { get { return _accuracyPlusOne - 1; } get { _accuracyPlusOne= value + 1; } } } 
+3
source share

I don't think C # allows you to create default constructors for value types. There are several questions related to your problem:

  • Why can't I define a default constructor for a structure in .NET?
  • How to force use factory in structure in C #?

There is a way to do this in IL, but initializing arrays will still not call these constructors.

+2
source share

Are you hoping to initialize precision to -1 with the default constructor? I do not think that you can forbid anyone to use new Value() , but you can add a constructor that allows you to use new Value(10) and have the initialization accuracy the way you want.

See the MSDN page on [Structural Constructors] ( http://msdn.microsoft.com/en-us/library/aa288208(VS.71).aspx) .

You can always throw an exception in code that uses your structure if you encounter precision 0 (if that value never makes sense!).

0
source share

All Articles