Design Guidelines– Classes vs. Structures


My goal is to cover some .NET 4 Platform features through a series of ‘guideline’ type entries demonstrating some new and existing functionality.

- April 20, 2015

Rest of the Story:

My goal is to cover some .NET 4 Platform features through a series of ‘guideline’ type entries demonstrating some new and existing functionality.  In this first entry, I have seen both classes and structures used throughout applications.  The following is meant to describe and explain good design considerations.
Structure types are well suited for modeling mathematical, geometrical, and other "atomic" entities in your application. A structure (like an enumeration) is a user-defined type; however, structures are not simply a collection of name/value pairs. Rather, structures are types that can contain any number of data fields and members that operate on these fields.

struct Point {
    // Fields of the structure.
    public int X;
    public int Y;
 
    // Add 1 to the (X, Y) position.
    public void Increment() {
        X++; Y++;
    }
 
    // Subtract 1 from the (X, Y) position.
    public void Decrement() {
        X--; Y--;
    }
 
    // Display the current position.
    public void Display() {
        Console.WriteLine("X = {0}, Y = {1}", X, Y);
    }
}
Using the structure Point myPoint;

myPoint.X=100; myPoint.Y=76; myPoint.Display();
You can create a structure using new keyword which will use the structures’ default constructor.
i.e. Point myPoint = new Point(); // each field will be automatically set to its default value
A custom constructor can also be created with a structure which allows you to specify the values of a field upon creation.
i.e. Public Point(int xpos, int ypos) Point p2 = new Point(50,50);

Class

A class is a user-defined type that is composed of field data (often called member variables) and members that operate on this data (such as constructors, properties, methods, events, and so forth). Collectively, the set of field data represents the "state" of a class instance (otherwise known as an object). The power of object-based languages such as C# is that by grouping data and related functionality in a unified class definition, you are able to model your software after entities in the real world.
I am going to jump to some less known aspects of a class.
Default constructor: By definition, a default constructor never takes arguments.  After allocating the new object into memory, the default constructor ensures that all field data of the class is set to an appropriate default value. Custom constructor:Allows the user with a simple and consistent way to initialize the state of an object directly at the time of creation.  Note however that as soon as you define a custom constructor the compiler removes the default constructor.  Thereby if you wish to continue to have both a default and custom constructors you must explicitly declare the default constructor.
Chaining constructors utilizes the ‘this’ keyword.  Understand that using the this keyword to chain constructor calls is never mandatory.  Notice in the example below however that the constructor Public Motorcycle(string name) takes one string argument but continues to call the additional constructor Public Motorcyle(int intensity, string name) via the this keyword i.e. this(0,name)

class Motorcycle
{
  public int driverIntensity;
  public string driverName;
 
  // Constructor chaining.
  public Motorcycle() {}
  public Motorcycle(int intensity)
    : this(intensity, "") {}
 
  public Motorcycle(string name)
    : this(0, name) {}
 
  // This is the 'master' constructor that does all the real work.
  public Motorcycle(int intensity, string name)
  {
    if (intensity > 10)
    {
      intensity = 10;
    }
    driverIntensity = intensity;
    driverName = name;
  }
...
}

Optional Arguments allow you to define supplied default values to the incoming arguments.  i.e. with the constructor below the user can create a new RocketShip with zero, one or two arguments.  This is a .NET 4 feature only. RocketShip = new RocketShip(); RocketShip = new RocketShip(name:=”TestShip”); RocketShip = new RocketShip(10); //sets speed = 10, leaving name =  ””

// Single constructor using optional args.
public RocketShip(int speed = 0, string name = ""){
  driverSpeed = speed;
  driverName = name;
}
  Classes vs. Structures Guidelines
  • Consider defining a structure instead of a class if instances of the type are small and commonly short-lived or are commonly embedded in other objects.

  • Do not define a structure unless the type has all 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.

If one or more of these conditions are not met, create a reference type instead of a structure. Failure to adhere to this guideline can negatively impact performance.