A class object has the advantage that it can pass a link to it, while the scope and lifetime of such a link is unlimited if it reaches external code. The advantage of the structure is that, although it can go around short-lived references to them, endless messy links can not be transmitted. This helps to avoid having to worry about whether such links exist.
Some people have suggested that owners of data that change should not be structures. I strongly disagree. Entities that exist for storing data should in many cases be structs especially if they are mutable. Eric Lippert has repeatedly published that he considers mutable value types to be evil (search for labels “mutable” and “struct”). Of course, it is true that .net allows you to do certain things with the help of mutable structures, which it should not, and does not conveniently allow some of the things that it should, but POD structures ("Plain Old Data") that do not have mutating methods, but instead, they expose their entire state through public fields, have very useful consistency in their behavior, which is not used with any other data type. Using the POD structure can confuse someone who is not familiar with how they work, but will make the program more readable for everyone who does it.
Consider, for example, the following code, assuming that EmployeeInfoStruct contains only value types and immutable types , such as String:
[employeeInfoStruct is a struct containing the following field]
public Decimal YearlyBonus;
[someEmployeeContainer is an instance of a class which includes the following method]
EmployeeInfoStruct GetEmployeeInfo (String id); // Just the signature - code is immaterial
[some other method uses the following code]
EmployeeInfoStruct anEmployee = someEmployeeContainer.GetEmployeeInfo ("123-45-6789");
anEmployee.YearlyBonus + = 100;
Eric Lippert complains that the above code will change the value in anEmployee, but this change will not affect the container. I would suggest that a good thing is that anyone who knows how structures work can look at the above code and know that writing to a structured variable will affect that variable, but will not affect anything else if the program later does not use any another method (maybe SetEmployeeInfo) to save this variable somewhere.
Now replace EmployeeInfoStruct with EmployeeInfoClass, which has a read / write property of type YearlyBonus. Using only the above information, what can be said about the relationship between writing for any production server and anEmployee? Depending on the implementation of the anEmployee class (which, if EmployeeInfoClass is not sealed, may or may not actually be EmployeeInfoClass) and someEmployeeContainer, the relationship between the objects can be anything. Writes:
- Do not affect others
- Update another in 'natural' mode
- Corrupt another in any way
Using structures containing only fields of value types or immutable classes, semantics will always be # 1. You do not need to look at the code of the structure itself or the container code to know this. In contrast, if anEmployee.Salary or someEmployeeContainer.GetEmployee is virtual, it is impossible to really know what semantics are.
It is important to note that if the structures are large, passing them by value or returning them from functions can be costly. It is generally best to pass large structures as ref parameters whenever possible. Although inline collections really don't do a good job of facilitating this use, it can make using a structure with hundreds of bytes cheaper than using a class.