According to MSDN (Section 11.3.6 of the C# spec):
Within an instance constructor of a struct,
thiscorresponds to anoutparameter of the struct type, and within an instance function member of a struct,thiscorresponds to arefparameter of the struct type. In both cases,thisis classified as a variable, and it is possible to modify the entire struct for which the function member was invoked by assigning tothisor by passingthisas areforoutparameter.
I don't get it.  How is this different for a struct than for a class?  Code examples are appreciated
Eric Lippert had a fabulous post on mutating readonly structs a while back that will really help clarify the issue for you. There's even a code example, and a quiz!
The salient point is that structs obey value semantics and classes do not and so this must mean something different 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) {
        p.x = 100;
        p.y = 100;
    }
}
but is not if "struct" is replaced by "class."
When you're dealing with structs, you're dealing with value types.
In a class, "this" is a reference to the current instance. This lets you mutate the class instance by setting properties/fields on the class.
However, if you're in a struct, things act differently. When you're in a struct's method, "this" lets you mutate the struct. However, if you're using this in a method, you're almost always dealing with a copy of the "original" struct.
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, the stranger part - this is valid, and what that quote was saying:
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
Jason's answer and Eric's post show one aspect of this which is interesting... but there's another which is even more alarming:
You can reassign this within a method, even if the type is otherwise immutable.
To demonstrate it, we'll use a struct which is stored in a non-readonly variable, but which contains a readonly 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);
    }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With