When you're working with large datasets you can often find yourself wanting to prevent creating a large number of "just in case" objects, particularly collections such as List. Any chance to avoid creating extra, unnecessary objects that exist only for the garbage collector to have to deal with is a welcome one.

class ClassName {
  public ClassName() {
    StringList = new List<String>();
  }

  public string Id { get; set; }
  public List<string> StringList { get; set; }
}

A simple, but not thread safe means of instantiating StringList would be…

class ClassName {
  private List<string> _StringList;

  public ClassName() { }

  public string Id { get; set; }
  public List<string> {
    get { return _StringList ?? (_StringList = new List<string>()); }
    set;
  }
}

That will get you by in a lot of coding situations, but eventually you may find yourself in a multi-threaded coding situation and need something thread safe…

class ClassName {
  private List<string> _StringList;
  private object _stringlistlock = new object();

  public ClassName() { }

  public List<string> {
    get {
      if (_StringList == null) {
        lock(stringlistlock) {
          // In case assignment happens between first check and locking call.
          if (_StringList == null) {
            _StringList = new List<string>();
          }
        }
      }
      return _StringList;
    }
    set;
  }
}

Now you're probably wondering why I would have a set option for the property when the get handles the instantiation. It's to support shorthand class instantiation.

Instead of writing…

ClassName cn = new ClassName();
cn.Id = "The Id";
cn.StringList.Add("A");
cn.StringList.Add("B");
cn.StringList.Add("C");
cn.StringList.Add("D");
cn.StringList.Add("E");

…we can write …

ClassName cn = new ClassName() { Id = "The Id", StringList = new List<string>(new string[] { "A", "B", "C", "D", "E" }) };

If you don't like or don't plan to use that class creation shorthand, and you are using DotNet 4 or later, you can use Microsoft's Lazy<T> methodology. It doesn't work with the shorthand because once a reference value has been set by doing the property get of the private backing variable, it can't be changed by a property set call.

Thanks to Stack Overflow, Marc Gravell, and Jim Mischel for some of this information.