Struct vs Class(improving the definition in the previous post)
There is a very important and commonly unknown difference between these two in .Net. The confusion sometimes stems from another source. Not knowing what value types and reference types actually are. Given that we have already gone through that, I will continue to shed more light into this matter.
The most correct way of differentiating between a struct and a class is that structs are value types and classes are reference types. Also another very well known answer to this question is that structs are allocated on the stack whereas reference types are allocated on the heap. This is also inaccurate as we showed in the previous section. Value types at times may be allocated on the heap. Even local variables when part of an anonymous method ends up on the heap. As Eric Lippert puts it in his article on this, the placing of value types on the stack is just an implementation detail. We should not be thinking of where the CLR is deciding to do with the value type or the reference type. That shouldn't point our decision. The real decision is in the semantics. Is the type a value or a reference ?
An article in MSDC elucidates this even further. There are some properties that a type should have in order to be a struct. If it doesn't have these properties, just define a class. The properties are as follows:
- The type represents a single logical value like other primitive values.
- It is immutable.
- It needs less than 16 bytes of memory.
- It is not boxed frequently.
Now let's see why each of these conditions have to apply. Firstly the type should represent a primitive type. This is what we mean by it being semantically a value type. If the type logically represents a single primitive value, it should be considered for being a value type.
Also, the type should be immutable. There is a very well known class that is immutable and we work with extensively. Yes, string. Ever wandered why strings are immutable? after all they're a reference type and a value type. The answer to this question is the same reasons we want our value types to be immutable. Firstly why are strings not classes now that they have some properties of a struct? They also represent a single logical value. But there is another side to this.
Strings can easily get over 16 bytes. They are passed around quite a lot., they are compared very often(they are often keys in dictionaries), they are usually repeated, operations like copy, range, etc are used often, etc. All of these properties bring lots of head ache if they are mutable. Being passed around creates all sorts of problems for threading since mutable objects have to be locked to avoid race conditions. Being compared often means that we have to parse through the two strings to find out if they are they same, where we could use interning to make all strings like "hello" to point to one memory reference and then we could just compare the memory locations. This also helps with repeated strings as all of them are now basically references to the same location which is immutable and wouldn't change. Also copying and range operations are made very easy with copying being only returning "this" and the range operations maybe being only "this" plus a start and end position maybe ? Basically put, what I want to impress upon you is the amount of compiler optimization is achieved when strings are made immutable. This is why a lot of languages like C#, Java and Python have opted for this design.
Okay, so after this rather lengthy digression. Let's get back to the task at hand. We were analyzing the reasons a type may be defined as a struct. We have come all the way to them being less that 16 bytes. I would say that the reason for this is that simply stacks are not that big ! In windows for example each thread is given an 1Mb array as its stack and this space is shared with lots of other elements. So it makes sense to use it sparingly.
Last but not least is the boxing issue. This is the most obvious property as the boxing/unboxing operation is expensive and has to be avoided if done in abundance.
No comments:
Post a Comment