6

All C# beginners know that class is a reference type and struct is a value one. Structures are recommended for using as simple storage. They also can implement interfaces, but cannot derive from classes and cannot play a role of base classes because of rather "value" nature.

Assume we shed some light on main differences, but there is one haunting me. Have a look at the following code:

public class SampleClass
{
    public void AssignThis(SampleClass data)
    {
        this = data; //Will not work as "this" is read-only
    }
}

That is clear as hell - of course we aren't permitted to change object's own pointer, despite of doing it in C++ is a simple practice. But:

public struct SampleStruct
{
    public void AssignThis(SampleStruct data)
    {
        this = data; //Works fine
    }
}

Why does it work? It does look like struct this is not a pointer. If it is true, how does the assignment above work? Is there a mechanism of automatic cloning? What happens if there are class inside a struct?

What are the main differences of class and struct this and why it behaves in such way?

Ilya Tereschuk
  • 1,204
  • 1
  • 9
  • 21
  • 3
    "It does look like struct this is not a pointer." Bingo. Structs are value types http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx – Ant P Jan 02 '14 at 21:40
  • agreed. structs "MOSTLY" live on the stack – T McKeown Jan 02 '14 at 21:41
  • 3
    @TMcKeown, no, they don't. Not always, anyway. – Frédéric Hamidi Jan 02 '14 at 21:42
  • @AntP Thanks, it is fair, but let's imagine: value type object assigns itself to other. In which way? – Ilya Tereschuk Jan 02 '14 at 21:42
  • @ElliotTereschuk I'm not sure what you mean by that. But I have a feeling that the answer is "by value." – Ant P Jan 02 '14 at 21:42
  • 4
    @TMcKeown Value types live where they've been defined, reference types always live on the heap. – volpav Jan 02 '14 at 21:44
  • @AntP I mean that behavior of `struct` `this` looks some confusing – Ilya Tereschuk Jan 02 '14 at 21:44
  • @lightbricko Thanks, now we know struct's this assignment clones even read-only fields. But why is it happening? – Ilya Tereschuk Jan 02 '14 at 21:46
  • @ElliotTereschuk it's a "feature", really :-) – volpav Jan 02 '14 at 21:48
  • @ElliotTereschuk It works that way, because it was specified to work that way. It’s all in the answer for the linked question. – poke Jan 02 '14 at 21:48
  • 1
    @ElliotTereschuk I'm not arguing that it's not confusing (in this context), which is why it's probably not a very good idea to use it. – Ant P Jan 02 '14 at 21:49
  • @ElliotTereschuk simply because it is the way it is supposed to work. You can read section 7.6.7 in the C# 5.0 language specification: http://www.ecosia.org/url?url=http%3A%2F%2Fwww.microsoft.com%2Fen-us%2Fdownload%2Fdlx%2Fthankyou.aspx%3Fid%3D7029&v=2&i=0&q=%227.6.7%22%20%22c%23%20language%22&p=0&tr=508&at=0&ar=0&ab=0&mr=0&ir=0&kgr=0&nr=0&iar=0&sr=0 – lightbricko Jan 02 '14 at 21:53

1 Answers1

9

This section of the C# specification is relevant here (11.3.6).

Of classes:

Within an instance constructor or instance function member of a class, this is classified as a value. Thus, while this can be used to refer to the instance for which the function member was invoked, it is not possible to assign to this in a function member of a class.

Of structs:

Within an instance constructor of a struct, this corresponds to an out parameter of the struct type, and within an instance function member of a struct, this corresponds to a ref parameter of the struct type. In both cases, this is classified as a variable, and it is possible to modify the entire struct for which the function member was invoked by assigning to this or by passing this as a ref or out parameter.

Ant P
  • 24,820
  • 5
  • 68
  • 105
  • That's for VS .NET 2003. In 2013 it's a little different, but still means the same. And it's *11.3.6* now :) – MarcinJuraszek Jan 02 '14 at 21:52
  • 1
    @MarcinJuraszek Noted and updated - the up-to-date documentation is actually a much friendlier definition. – Ant P Jan 02 '14 at 21:58
  • Hmm, seems the link still points to the 2003 documentation and the latest version is only available as a download link - the principle is presumably the same. – Ant P Jan 02 '14 at 22:04
  • Yes, looks like *11.3.6* has not been changed since then. – MarcinJuraszek Jan 02 '14 at 22:05