The codebase I’m working in now has the convention of using private fields and public properties. For example, most classes have their members defined like this:
// Fields
private double _foo;
private double _bar;
private double _baz;
// Properties
public double Foo
{
get{ return _foo; }
set{ _foo = value; }
}
public double Bar
{
get{ return _bar; }
set{ _bar = value; }
}
public double Baz
{
get{ return _baz; }
}
I know these can be rewritten without their internal private properties:
public double Foo{ get; set; }
public double Bar{ get; set; }
public double Baz{ get; private set; }
I’d like some input on this:
- Is there a good reason to prefer the older, more explicit style over the
newer, more concise one? - Should I write any new classes using the
concise style, or should I try to match the older code for
consistency? Is consistency worth enough in this case to justify the older format?
5
There are a couple instances where the so-called “older” style is still required:
A: Immutable types using language-provided immutability. The readonly
modifier in C# freezes that value after construction. There’s no way to mimic this with automatically-implemented properties (yet).
public sealed class FooBarBazInator
{
private readonly double foo;
public FooBarBazInator(double foo)
{
this.foo = foo;
}
public double Foo
{
get
{
return this.foo;
}
}
}
B: Your getters/setters have any logic whatsoever. WPF and Silverlight (and similar) code that are data-bound to your classes will implement INotifyPropertyChanged
like so:
public class FooBarBazInator : INotifyPropertyChanged
{
private double foo;
public event PropertyChangedEventHandler PropertyChanged;
public double Foo
{
get
{
return this.foo;
}
set
{
this.foo = value;
this.RaisePropertyChanged("Foo");
}
}
private void RaisePropertyChanged(string propertyName)
{
var propertyChanged = this.PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Other than those, I’d say use the new style. Keeps your code concise and offers less surface area for bugs to creep in. Plus, if it ever needs to change to include logic, it won’t be signature-incompatible.
5
I would say that having explicit backing field is just useless cruft: it makes your code longer and harder to read. It also adds potential of error:
public double Bar
{
get { return _baz; }
set { _bar = value; }
}
I think an error like this could happen quite easily and would be quite hard to spot.
And if you want consistency, do it the other way: change code that uses backing fields into code that uses automatic properties. This is especially easy if you use a refactoring tool like ReSharper (and if you don’t use something like that, I think you should start).
Of course, there are still cases where having backing field is necessary, but I think that’s not relevant to this question.
1
Even though the question is quite old I thought of adding couple of points which I read from a book worth mentioning here.
-
The run-time serialization engines persist the name of the filed in a serialized stream. The name of the backing field for an Automatically implemented property ( AIP )is determined by the compiler, and it could actually change the name of this backing field every time you recompile your code, negating the ability to deserialize instances of any types that contain an AIP. So do not use AIP with any type you intend to serialize or deserialize .
-
When debugging, you cannot put a breakpoint on an AIP get or set method, so you cannot easily detect when an application is getting or setting this property. You can set breakpoints on manually implemented breakpoints
1
Properties without fields are better for readability but if the class is decorated with a [Serializable] attribute then you should keep the backing field.
Note also that with VS 2019 the “Use auto property” quick action is disabled for the same reason.
Is there a good reason to prefer the older, more explicit style over the newer, more concise one?
Not really. Though I would argue that any time you had a pass through property like that, you should’ve just used a public field to begin with.
Should I write any new classes using the concise style, or should I try to match the older code for consistency? Is consistency worth enough in this case to justify the older format?
Assuming you ignored the above advice and have passthrough properties, I would not aim to match the style. Ideally, you would go back and refactor the old style into the new style to be consistent, but the chance of people misreading that code is slim.
7