When should I use a struct instead of a class?

MSDN says that you should use structs when you need lightweight objects. Are there any other scenarios when a struct is preferable over a class?

Some people might have forgotten that:

  1. structs can have methods.
  2. structs cannot be inherited.

I understand the technical differences between structs and classes, I just don't have a good feel for when to use a struct.


Solution 1:

MSDN has the answer: Choosing Between Classes and Structures.

Basically, that page gives you a 4-item checklist and says to use a class unless your type meets all of the criteria.

Do not define a structure unless the type has all of the following characteristics:

  • It logically represents a single value, similar to primitive types (integer, double, and so on).
  • It has an instance size smaller than 16 bytes.
  • It is immutable.
  • It will not have to be boxed frequently.

Solution 2:

I am surprised I have not read at any of the previous answer this, which I consider the most crucial aspect :

I use structs when I want a type with no identity. For example a 3D point:

public struct ThreeDimensionalPoint
{
    public readonly int X, Y, Z;
    public ThreeDimensionalPoint(int x, int y, int z)
    {
        this.X = x;
        this.Y = y;
        this.Z = z;
    }

    public override string ToString()
    {
        return "(X=" + this.X + ", Y=" + this.Y + ", Z=" + this.Z + ")";
    }

    public override int GetHashCode()
    {
        return (this.X + 2) ^ (this.Y + 2) ^ (this.Z + 2);
    }

    public override bool Equals(object obj)
    {
        if (!(obj is ThreeDimensionalPoint))
            return false;
        ThreeDimensionalPoint other = (ThreeDimensionalPoint)obj;
        return this == other;
    }

    public static bool operator ==(ThreeDimensionalPoint p1, ThreeDimensionalPoint p2)
    {
        return p1.X == p2.X && p1.Y == p2.Y && p1.Z == p2.Z;
    }

    public static bool operator !=(ThreeDimensionalPoint p1, ThreeDimensionalPoint p2)
    {
        return !(p1 == p2);
    }
}

If you have two instances of this struct you don't care if they are a single piece of data in memory or two. You just care about the value(s) they hold.