It’s allowed and common practice to have fields/properties that share the same name as their type. First example that comes to mind from the FCL is DispatcherObject.Dispatcher
, which returns an instance of type Dispatcher
.
However, I personally prefer to avoid declaring fields as protected, and use properties instead. If you want to avoid the coding involved with declaring a backing field, you may use an auto-implemented property:
protected Foo Foo { get; set; }
The advantage of using properties is that you can apply different access modifiers for the getter and the setter:
protected Foo Foo { get; private set; }
Edit: The advantage of using protected properties instead of protected fields is that they allow you to change their implementation – for example, to introduce value validation or change notification – without breaking external libraries that might access it.
Suppose, for example, that you want to extend your class to implement INotifyPropertyChanged
. If you were using a protected field, there would be no straightforward way of detecting when the value of the field is changed by a consuming assembly (unless you change the implementation of the external assembly as well). If you were using a protected property, you could simply alter its implementation without requiring any changes in consuming assemblies:
private Foo foo;
protected Foo Foo
{
get
{
return foo;
}
set
{
if (foo != value)
{
foo = value;
OnPropertyChanged("Foo");
}
}
}
Edit2: Several more advantages to using properties over fields are given in LBushkin’s answer.
Changing a field to a property does appear to break the ABI. I haven’t yet found it stated in an authoritative source (I didn’t spend too much time looking); however, per pst’s comment:
The code behind the property can be changed (to use a custom private backing field or whatever). However, changing a Public Member Variable to a Property is a breaking change in the ABI (Application Binary Interface).
Per jstedfast’s answer:
First thing to keep in mind is that property accessors are compiled into methods. This means that it has a different ABI from just reading/writing to a class member variable, even though it may syntactically look the same.