I guess it's another way to say "it has value semantics"
–
TrapFeb 20 '09 at 21:22

1

They've probably recommended this because if the struct is immutable, then it won't matter that it has value semantics rather than reference semantics. The distinction only matters if you mutate the object/struct after making a copy.
–
Stephen C. SteelMar 26 '10 at 22:07

1

@Chuu: In designing the JIT compiler, Microsoft decided to optimize the code for copying structs which are 16 bytes or smaller; this means that copying a 17-byte struct may be significantly slower than copying a 16-byte struct. I see no particular reason to expect Microsoft to extend such optimizations to larger structs, but it's important to note that while 17-byte structurs may be slower to copy than 16-byte structs, there are many cases where large structs may be more efficient than large class objects, and where the relative advantage of structs grows with the size of the struct.
–
supercatJan 2 '13 at 16:12

1

@Chuu: Applying the same usage patterns to large structures as one would to classes is apt to result in inefficient code, but the proper solution often not to replace the structs with classes, but instead to use structs more efficiently; most notably, one should avoid passing or returning structs by value. Pass them as ref parameters whenever it's reasonable to do so. Pass a struct with 4,000 fields as a ref parameter to a method which changes one will be cheaper than passing a struct with 4 fields by value to a method which returns modified version.
–
supercatJan 2 '13 at 16:18

an object is supposed to be read only(every time you pass/assign a struct it gets copied). Read only objects are great when it comes to multithreaded processing as they don't requite locking in most cases.

an object is small and short-living. In such a case there is a good chance that the object will be allocated on the stack which is much more efficient than putting it on the managed heap. What is more the memory allocated by the object will be freed as soon as it goes outside its scope. In other words it's less work for Garbage Collector and the memory is used more efficient.

I have always used a struct when I wanted to group together a few values for passing things back from a method call, but I won't need to use it for anything after I have read those values. Just as a way to keep things clean. I tend to view things in a struct as "throwaway" and things in a class as more useful and "functional"

As @Simon said, structs provide "value-type" semantics so if you need similar behavior to a built-in data type, use a struct. Since structs are passed by copy you want to make sure they are small in size, about 16 bytes.

If an entity is going to be immutable, the question of whether to use a struct or a class will generally be one of performance rather than semantics. On a 32/64-bit system, class references require 4/8 bytes to store, regardless of the amount of information in the class; copying a class reference will require copying 4/8 bytes. On the other hand, every distinct class instance will have 8/16 bytes of overhead in addition to the information it holds and the memory cost of the references to it. Suppose one wants an array of 500 entities, each holding four 32-bit integers. If the entity is a structure type, the array will require 8,000 bytes regardless of whether all 500 entities are all identical, all different, or somewhere between. If the entity is a class type, the array of 500 references will take 4,000 bytes. If those references all point to different objects, the objects would require an additional 24 bytes each (12,000 bytes for all 500), a total of 16,000 bytes--twice the storage cost of a struct type. On the other hand, of the code created one object instance and then copied a reference to all 500 array slots, the total cost would be 24 bytes for that instance and 4,000 for the array--a total of 4,024 bytes. A major savings. Few situations would work out as well as the last one, but in some cases it may be possible to copy some references to enough array slots to make such sharing worthwhile.

If the entity is supposed to be mutable, the question of whether to use a class or struct is in some ways easier. Assume "Thing" is either a struct or class which has an integer field called x, and one does the following code:

Thing t1,t2;
...
t2 = t1;
t2.x = 5;

Does one want the latter statement to affect t1.x?

If Thing is a class type, t1 and t2 will be equivalent, meaning t1.x and t2.x will also be equivalent. Thus, the second statement will affect t1.x. If Thing is a structure type, t1 and t2 will be different instances, meaning t1.x and t2.x will refer to different integers. Thus, the second statement will not affect t1.x.

Mutable structures and mutable classes have fundamentally different behaviors, though .net has some quirks in its handling of struct mutations. If one wants value-type behavior (meaning that "t2=t1" will copy the data from t1 to t2 while leaving t1 and t2 as distinct instances), and if one can live with the quirks in .net's handling of value types, use a structure. If one wants value-type semantics but .net's quirks would cause lead to broken value-type semantics in one's application, use a class and mumble.

I wouldn't use garbage collection as an argument for/against the use of structs vs classes. The managed heap works much like a stack - creating an object just puts it at the top of the heap, which is almost as fast as allocating on the stack. Additionally, if an object is short-lived and does not survive a GC cycle, deallocation is free as the GC only works with memory that's still accessible. (Search MSDN, there's a series of articles on .NET memory management, I'm just too lazy to go dig for them).

Most of the time I use a struct, I wind up kicking myself for doing so, because I later discover that having reference semantics would have made things a bit simpler.

Anyway, those four points in the MSDN article posted above seems a good guideline.

If you sometimes need reference semantics with a struct, simply declare class MutableHolder<T> { public T Value; MutableHolder(T value) {Value = value;} }, and then a MutableHolder<T> will be an object with mutable class semantics (this works just as well if T is a struct or an immutable class type).
–
supercatFeb 2 '13 at 0:08

Structs are on the Stack not the Heap so therefore they are thread safe, and should be used when implementing the transfer object pattern, you never want to use objects on the Heap they are volatile, you want in this case to use the Call Stack, this is a basic case for using a struct I am surprised by all the way out answers here,