Classes and structures can contain, among other types of members, fields and properties. In this post I’ll focus on field and property members and explain the difference between instance fields/properties and static fields/properties. Before reading further here’s a short video on the topic:

The Purpose of Fields and Properties

Fields are used to store object state data, and properties are used to set and query object state data. An instance field stores state data for individual objects, that is, every object of a particular type will have its very own copy of any and all instance fields defined for that class or structure type. A static field stores state data for all instances of the type. In other words, a static field’s value is shared by all instances of the type. Let’s take a look at an example.

using System;

public class Employee {
  //Instance Fields 
  private string _firstName; 
  private string _middleName; 

  //Instance Properties 
  public string FirstName {
    get {return _firstName;} 
    set {_firstName = value;} 
  } 

  public string MiddleName {
    get {return _middleName;}
    set {_middleName = value;}
  } 

  public string LastName {
    get;
    set;
  }

  //Static Properties 
  public static int Count {
    get; 
    private set; 
  } 

 //Constructors 
 public Employee(string firstName, string middleName, string lastName){
   _firstName = firstName; 
   _middleName = middleName; 
   LastName = lastName; 
   Employee.Count++; 
 } 

 public Employee():this("John", "J", "Doe"){}

 //Overridden Object Methods 
 public override string ToString(){
   return _firstName + " " + _middleName + " " + LastName; 
 } 
}

Referring to the Employee class – I’ve defined two private fields _firstName and _middleName. These explicit field definitions are used as backing fields for the FirstName and MiddleName public properties, as you can clearly see from the code. If you use fields in this manner, there’s no need to explicitly declare them. Simply use Auto-Implemented properties as I’ve done with the LastName property. As their name implies, auto-Implemented properties automatically create the backing field behind the scenes. This reduces the amount of boilerplate code you need to write.  I’ve mixed the two styles in this example for demonstration purposes. The Count property is a static, class-wide property declared with the help of the static keyword. I increment this value whenever an employee object is created. Note that you must access static properties via the class name. Lastly, in this example, I have overridden the Object.ToString() method.  To demonstrate this code I’ll need another class that implements a Main() method.

using System;

public class MainApp {
  public static void Main(){
   Employee e1 = new Employee();
   Employee e2 = new Employee("Rick", "W", "Miller");
   Console.WriteLine(e1); 
   Console.WriteLine(e2); 
   Console.WriteLine(Employee.Count); 
  }
}

Referring to the MainApp class – I create two instances of Employee, testing both versions of the constructor. I then write their values to the console and then, with the help of the static Employee.Count property, I write the number of employee objects created. Figure 1 shows the results of running this program.

Figure 1 – Results of Running MainApp

Figure 1 – Results of Running MainApp

Parting Thoughts

If all objects of a class need access to shared state data use static fields and properties. Fields are fine if only the internal code of the class needs access, but if you think at some point in the future client code will need access to that data, use a property. The rule of thumb is to keep fields private for encapsulation and properties public. Use instance fields and properties if the state data is unique to each object.

 

Rick Miller
Falls Church, VA