C# FAQ

Structs

Q: What do structs buy you?
A: Structs can sometimes improve performance.

Q: How are structs different from classes?
A: Structs are stored on the stack as opposed to the heap. Structs are value types rather than reference types.

Q: How do structs impair code readability and maintainability?
A: What will this code snippet print?
   Point a = new Point(10, 10);
Point b = a;
a.x = 100;
Console.WriteLine(b.x);
The answer depends on whether Point is a class or a struct. If Point is a class then the answer is 100. If Point is a struct then the answer is 10.

Even though structs and classes work differently, they look the same. This makes the code hard to follow. C# violates a principle of programming language design, known as the principle of uniformity.

Q: What is the principle of uniformity and why should I care?
A: In The Psychology of Computer Programming, Weinberg explains that uniformity is a psychological principle which says that users/programmers expect that things that look similar should do similar things, and conversely that things that look different should do different things.

If a programming language violates this principle then it increases complexity, and code written in that language becomes harder to understand and maintain.

Because of C#'s violation of the principle of uniformity, the programmer has the extra burden of tracking whether something is a struct or a class.

Q: Isn't that a problem in C++ too?
A: No. In C++, structs and classes work the same. The only difference is the default visibility for fields and methods. Also, in C++ the syntax for using a class/struct reference is very different from the syntax for using a class/struct value.

Q: Why should I track whether something is a struct or a class?
A: It's a huge semantic difference. A class variable holds a reference to to a heap-allocated object, while a struct variable directly holds the value of the object.

In C++, this is usually visible in the declaration of the variable (Foo f for a value type, Foo *pF for a pointer) and in its use (f.x for a value type, f->x for a reference type).

In C#, both use the same syntax for declaration and use, and there isn't even any suggested name standard to mark the difference.

In just about every case, it's important to know if you are dealing with value types or reference types — reference types has the concept of identity and equality, while value types only has equality. Allocating an array of value types gives you a number of objects with default values while an array of reference types gives you a array of null references. Adding a struct type to a list means it's silently boxed and removing it unboxes it at a significantly higher cost than if a reference types were added removed. Etc, etc.

[credit: Mats Olsson]

Q: What can we conclude from all this?
A: Structs buy very little when weighed against the maintenance headaches its use is likely to cause.

C# Best Practice

Do not use structs

[Back to Index]













1