I noticed that the semantics of the workings of the " this " keyword in user structures and classes are completely different.
For example, in the structure we can do something like this:

struct MyStruct { int x,y; void Reset() { this = new MyStruct(); // удаляем предыдущую структуру и создаем новую О_О } } 

I would like to see the whole difference between the This keyword, between the structure and the class, as well as to find out what is going on under the hood.

2 answers 2

The most important difference is that the this variable for a structured type must be explicitly assigned in the structure's constructor.

A variable of structural type, and this for structures is a variable of structural type, is considered explicitly assigned if each of its fields is explicitly assigned.

How does this affect structures?

This affects the work of designers. Consider the following sample structure declaration.

 struct EvenOdd { int x, y; void make_even() { x &= ~0 << 1; } void make_odd() { y |= 1; } public EvenOdd( int x, int y ) { this.x = x; make_even(); this.y = y; make_odd(); } } 

For this structure declaration, the compiler will give an error message

Error CS0188 Cannot use this object until all its fields have been assigned.

because at the point of calling the make_even method this is not yet explicitly assigned , because the data member of structure y has not yet been initialized.

After exiting the constructor, the this variable is assumed to be explicitly assigned .

You can make the previous structure constructor valid by first calling the default constructor.

  public EvenOdd( int x, int y ) : this() { this.x = x; make_even(); this.y = y; make_odd(); } 

In this case, inside the body of the constructor with parameters, the this variable will already be explicitly assigned .

If you change this declaration to a class declaration, then there will be no problems with this , where this no longer a variable, but a value, and this class will be successfully compiled.

 class EvenOdd { int x, y; void make_even() { x &= ~0 << 1; } void make_odd() { y |= 1; } public EvenOdd( int x, int y ) { this.x = x; make_even(); this.y = y; make_odd(); } } 

    I think, better than the language specification, no one will answer you. (By the way, the specification is on your computer, <Visual studio dir> \ VC # \ Specifications \ 1033 \ CSharp Language Specification.docx.)

    I will translate section 7.6.7.

    Access through this allowed only in the body of a non-static constructor, method, or accessor [this is a getter or setter - VladD ]. The meaning of this is:

    • When used inside a non-static constructor, this considered a value . The type of this value is the type [of the instance] (see §10.3.1) of the class in which it is used, and the value is a reference to the constructed object.
    • When used inside a non-static method or accessor, this regarded as a value . The type of this value is the type [instance] (see §10.3.1) of the class in which it is used, and the value is a reference to the object that has a method or an accessor called.
    • When used inside a non-static constructor, this structure is regarded as a variable . The type of this variable is the type of [instance] (see §10.3.1) of the structure in which the use occurs, and the value represents the structure being constructed. The variable this in the constructor [instance] of the structure behaves exactly like the out parameter of the same type; in particular, this means that the variable must be guaranteed to be initialized on any path of the constructor.
    • When used inside a non-static method or accessor, this regarded as a variable . The type of this variable is the type of [instance] (see §10.3.1) of the structure in which it is used.
      • If a method or accessor is not an iterator (see §10.14), this variable represents the structure for which the method or accessor was called and behaves exactly like the ref parameter of this type.
      • If the method or accessor is an iterator, the variable this represents a copy of the structure for which the method or accessor was called and behaves exactly as a parameter of the same type, passed by value.

    (I simplified the text a bit by removing the reference to the primary-expression .)


    It can be seen that for classes this represents a value, and for structures it is a variable. Therefore, structures can be assigned to this variable.