06 November 2003

Type Fundamentals

When possible, you should use value types instead of reference types because your application's performance will be better. In particular, you should declare a type as a value type if all of the following are true:

  • The type acts like a primitive type.
  • The type doesn't need to inherit from any other type.
  • The type will not have any other types derived from it.
  • Objects of the type are not frequently passed as method arguments since this would cause frequent memory copy operations, hurting performance. The next section on boxing and unboxing will explain this in more detail.
System.ValueType overrides the Equals method so that it returns true if the values of the two objects' instance fields match. In addition, System.ValueType overrides the GetHashCode method so that it produces a hash code value using an algorithm that takes into account the values in the objects' instance fields. When defining your own value types, it is highly recommended that you override and provide explicit implementations for the Equals and GetHashCode methods.

Since you cannot declare a new value type or a new reference type using a value type as a base class, value types should not have virtual functions, cannot be abstract, and are implicitly sealed (a sealed type cannot be used as the base of a new type).

The C# compiler automatically generates boxing and unboxing code. This makes programming easier, but it hides the overhead from the programmer who is concerned with performance.

if a value type doesn't override a virtual method defined by System.ValueType, then this method can only be called on the boxed form of the value type. This is because only the boxed form of the object has a pointer to a virtual method table. Methods defined directly with the value type can be called on boxed and unboxed versions of the value.