It is clear from the table that structures possess many of the features and capabilities of classes. Consequently, a developer may have difficulty deciding which is the better choice. The answer lies in understanding the few—but significant—differences between the two.
Structures Are Value Types and Classes Are Reference Types
As mentioned, classes are allocated space from the managed heap when the object or class instance is created. The address of the object (on the heap) is returned to the variable representing the object. In contrast, a variable set to a
struct
type contains the structure's actual data—not a pointer. The
ramifications
of this are most pronounced when passing arguments to functions. Reference types simply require that a pointer be passed, whereas structures require that a copy of all fields be made and passed to the function.
The structure does have some advantages with regard to memory allocation and Garbage Collection. Structure instances are allocated in a thread's stack rather than the managed heap, thus avoiding the associated overhead of managing pointers. Memory management is also simpler. When a copy of a structure is no longer
reachable
, its memory is collected and made available. In contrast, classes often require special code to handle unmanaged resources or invoke the system's garbage collection routine. Garbage Collection is covered in the
next
chapter.
Unlike a Class, a Structure Cannot Be Inherited
This is a
departure
from C++ conventions that permit a class to use an existing structure as a base class and permit a structure to use a class as a base. Is the .NET lack of support for this a step backward? Not really. It better delineates the role of the structure versus the class—making the structure less of a pseudo-class and more of a data structure. In addition, it provides for a more efficient implementation of the structure. The restriction enables the compiler to minimize the amount of administrative code that would be required to support inheritance. For example, because the compiler
knows
that a structure's methods cannot be overridden by subclasses, it can optimize the method invocation by expanding the method code inline rather than executing a method call.
General Rules for Choosing Between a Structure and a Class
The
easiest
way to make the choice is to compare the features of the type that you are designing with the following checklist.
If any of these are true, you should use a class
.
-
The type needs to serve as a base for deriving other types.
-
The type needs to inherit from another class. Note that although a structure cannot explicitly specify a base class, it does implicitly inherit from the
System.ValueType
and may override the inherited methods.
-
The type is frequently passed as a method parameter. Performance degrades as copies of the structure are created with each call. An exception to this is when the structure exists inside an array. Because an array is a reference type, only a pointer to the array is passed.
-
The type is used as the return type of methods. In the case where the return type is a structure, the system must copy the structure from the called function to the calling program.