Why have empty get set properties instead of using a public member variable? [duplicate]

One word: inheritance.

Properties are inheritable while fields are not. You can use fields in an inherited class, but not alter their behavior by making them virtual.

Like so:

public class Foo {
  public virtual int MyField = 1; // Nope, this can't

  public virtual int Bar {get; set; }
}

public class MyDerive : Foo {
  public override MyField; // Nope, this can't

  public override int Bar {
    get {
      //do something;
    }
    set; }
}

Edit: Besides the fact of inheritance, the points pointed out in the other answers (like visibility) are also a huge benefit of properties over fields.


One thing you can do with properties that you can't do with fields is limit visibility for either setter or getter:

public string MyProperty { get; private set; }

Something I use quite a lot.

And something (more powerful) you can't do with fields is define them inside an interface. Suppose you want an interface that requires implementing classes to have a certain property:

public interface MyInterface
{
    string MyProperty { get; }
}

Note that you do not need to have a setter here. It is entirely up to implementing classes to determine how they should set MyProperty.


Fields cannot be exposed in interfaces. And the auto-property can be changed into a "normal" property at any time if needed, without having the signature and interface of the class changing.

In general, fields are considered to be an implementation detail, which may change in future versions of the code. Therefore, you should expose data via methods and properties, leaving the way open for internal changes in the future which do not affect code using the class.


A property gives you several advantages over a simple public field:

  • you can control whether the property is read-only, write-only, or read/write
  • you can hide the actual implementation (maybe in the setter you want to do more than just setting a value)
  • when using databinding (e.g. in ASP.NET), you'll have to use properties (does not work with fields)