The value of this for structure (C #)

According to MSDN (section 11.3.6 of the C # specification ):

Inside the constructor of the instance constructor, this corresponds to an out parameter of the structure type and inside the member of the instance function struct, this corresponds to a ref parameter of the structure type. In both cases, this classified as a variable, and you can change the whole structure for which a member of the function was called by assigning this or passing this as a ref or out parameter.

I do not understand. How is this different for structure than for class? Sample code appreciated

+6
c #
source share
3 answers

Eric Lippert had a fabulous post about mutating readonly struct a backwards, which will really help clarify the problem for you. There's even a code example and a poll!

The essential point is that struct obeys the semantics of values, and class es does not, and therefore this means something else for the two. this is readonly for a class , but not for a struct . The following code is legal

 struct Point { public int x; public int y; public Point(int x, int y) { this.x = x; this.y = y; } public void DoGoTime() { GoTime(ref this); } public static void GoTime(ref Point p) { px = 100; py = 100; } } 

but not if " struct " is replaced by " class ".

+11
source share

When you are dealing with structures, you are dealing with types of values.

In the class, this is a reference to the current instance. This allows you to mutate an instance of a class by setting properties / fields in the class.

However, if you are in the structure, everything acts differently. When you are in the struct method, "this" allows you to mutate the structure. However, if you use this in a method, you almost always deal with a copy of the "original" structure.

For example:

 struct Test { int i; void Mutate() { this.i += 1; } } 

When you use this:

 void MutateTest(Test instance) { instance.Mutate(); } { Test test = new Test(); test.i = 3; Console.WriteLine(test.i); // Writes 3 test.Mutate(); // test.i is now 4 Console.WriteLine(test.i); // Writes 4 MutateTest(test); // MutateTest works on a copy.. "this" is only part of the copy itself Console.WriteLine(test.i); // Writes 4 still } 

Now part of the stranger is really what this quote said:

 struct Test { public Test(int value) { this.i = value; } int i; void Mutate(int newValue) { this = new Test(newValue); // This wouldn't work with classes } } /// { Test test = new Test(); test.i = 3; Console.WriteLine(test.i); // Writes 3 test.Mutate(4); Console.WriteLine(test.i); // Writes 4 
+6
source share

Jason's answer and Eric's post show one aspect of this that is interesting ... but there is another that is even more disturbing:

You can reassign this inside the method, even if the type is otherwise immutable.

To demonstrate this, we will use a structure that is stored in a variable other than readonly, but which contains a read-only field:

 using System; public struct LooksImmutable { private readonly int value; public int Value { get { return value; } } public LooksImmutable(int value) { this.value = value; } public void GoCrazy() { this = new LooksImmutable(value + 1); } } public class Test { static void Main() { LooksImmutable x = new LooksImmutable(5); Console.WriteLine(x.Value); x.GoCrazy(); Console.WriteLine(x.Value); } } 
+6
source share

All Articles