Why is it possible to create a structure without a new keyword?

Why are we not forced to instantiate the structure, for example, when using a class?

+22
instantiation c # struct
Oct. 14 '11 at 12:35
source share
7 answers

Why simple - because the spec says . How to ensure that the entire memory block is “definitely assigned”, which means: assigning a value to each field of the structure. However, this requires 2 unpleasant things:

  • public fields (almost always bad)
  • mutable fields (usually bad in structure)

therefore, in most cases with best practice, you need to use the new(...) syntax to call the constructor (or zero - memory for the constructor without parameters) for the correct type.

+17
Oct. 14 2018-11-12T00:
source share

Why are we not forced to create a structure using "new", for example, when using a class?

When you are a “new” reference type, three things happen. First, the memory manager allocates space from long-term storage. Secondly, a reference to this space is passed to the constructor, which initializes the instance. Thirdly, this link is passed back to the caller.

When you are a “new” type of meaning, three things happen. First, the memory manager allocates space from short-term storage . Secondly, the constructor receives a link to short-term storage. After starting the constructor, the value that was in the short-term storage is copied to the storage for the value, wherever it is. Remember that value type variables retain the actual value.

(Note that the compiler is allowed to optimize these three steps in one step, if the compiler can determine that it never provides partially constructed structure code for the user. That is, the compiler can generate code that simply passes the link to the final storage location for the constructor, thereby preserving one selection and one copy.)

So, now we can solve your question, which you actually asked back. It would be better to ask:

Why are we forced to allocate a class with "new" instead of just initializing the fields as with a structure?

You must highlight the class with the “new” because of these three things in the list. You need new memory allocated from a long-term storage, and you need to pass a link to this storage to the constructor. “new” is an operator that knows how to do this.

You do not need to call the “new” in the structure, because there is no need to allocate the “final” storage; the final repository already exists . The new value will go somewhere, and you have already received this store in other ways. Value types do not need a new distribution; all they need is initialization. All you have to do is make sure that the repository is properly initialized, and you can often do this without calling the constructor. Of course, this means that you run the risk of having a variable of type value that can be observed in a partially initialized state according to the user code.

To summarize: calling ctor is optional for value types, because when you initialize an instance of a value type, you don’t need to allocate new memory, but because skipping the constructor’s call means you can skip the short-term allocation and copy, the price you pay for this increase performance, lies in the fact that user code can see a partially initialized structure.

+48
Oct 14 2018-11-11T00:
source share

Because structure is a type of value. When you declare a variable, an instance immediately appears.

Therefore, the constructor ( new operator) is optional for the structure.

To consider

 struct V { public int x; } class R { public int y = 0; } void F() { V a; // a is an instance of V, ax is unassigned R b; // b is a reference to an R ax = 1; // OK, the instance exists //by = 2; // error, there is no instance yet a = new V(); // overwrites the memory of 'a'. ax == 0 b = new R(); // allocates new memory on the Heap by = 2; // now this is OK, b points to an instance } 
+11
Oct. 14 '11 at 12:37
source share

Because structures are value types, and classes are reference types. Thus, structures belong to the same category as int, double, etc.

+10
Oct. 14 '11 at 12:36
source share

After a year and a half ...

struct usually passed by value, and class always passed by reference. You probably well understand what happens when an object is passed by reference. When an object is passed by value, its contents, and not a reference to the object, is passed. It seems to the programmer that a small copy of the object is made. Changing one instance will not change another.

All variables (including fields and properties) are always allocated space for them while they exist. It is important to note that local variables do not exist until they are assigned a value in newer versions of C #. In the case of class -type variables, the allocated space will contain a reference to the contents of the object. In the case of the variable struct -type, the allocated space will contain the actual contents of the object.

So let's say you have an "empty" class -type variable. It will have a default link. This link will be null . However, the variable struct -type is not a reference: it is the actual contents of the object. When left “empty”, all its fields (and automatically implemented properties that are backed by fields behind the scenes) all contain default values ​​— in other words, they are also “empty”. If they are reference types, they will be null ; if they are value types, they will be 0 or the structures will be nullified (and the chain continues).

For the same reason, structs cannot have a default constructor. Just like you cannot override what a class looks like when it is null , you cannot override what a struct looks like when it is nullified.

There is an underused statement to get the default value of any class type--, struct or inline. This is the operator by default() . For example:

 class ClassType { } struct StructType { } // // ... // var classA = default(ClassType); var classB = (ClassType)null; if (classA == classB) { // This will execute, because both equal null. } var structA = default(StructType); var structB = new StructType(); if (structA == structB) { // This will execute, because both are zeroed. } // // ... // /// <summary> /// An example use case for the <c>default()</c> operator. /// </summary> /// <returns> /// <c>null</c> if <c>T</c> is a reference type, a zeroed instance <c>T</c> is a /// <c>struct</c>, or <c>0</c> if <c>T</c> is an intrinsic type. /// </returns> private static T GetDefault<T>() { // This line wouldn't compile, because T could be a value type. //return null; // This line wouldn't compile, because T could be a reference type without a default or accessible constructor. //return new T(); // This will work! return default(T); // In newer versions of C#, when the type is known from the context, it can be omitted: //return default; } 
+2
Apr 23 '13 at 22:09
source share

As said by David Heffernan and Henk Holterman , because structures are types of values ​​and therefore are created upon declaration. For a better understanding of ValueType and ReferenceType, please check this P Daddy link . It is explainable.

0
Oct 14 '11 at 12:43
source share

In addition to what was published: note that a structure cannot have a constructor without parameters or have an initializer for any of its instance fields. The default value has all fields of the value type set for their default value (for example, for int, false for bool, etc.), and all fields of the reference type are null.

Secondly, the structure is initialized, for example, by calling the constructor or using default() .

0
Oct. 14 '11 at 12:44
source share



All Articles