private List _dates;
public List Dates
{
get { return _dates; }
set { _dates = value; }
}
OR
publi
As long as you don't have to make sure the List<Date>
is initialized in the getter you are fine with both versions. I just suggest that you are using one version and you don't mix it in your code...
If you need it initialized you have to go for the first version...
private List<Date> _dates;
public List<Date> Dates
{
get { if (_dates == null) _dates = new List<Date>(); return _dates; }
set { _dates = value; }
}
I tend to use auto properties more because a property is a good way to express intent about what your object is doing, but still have some protection.
Almost all of my property declarations look like:
public bool IsBlah { get; private set; }
This makes it a nice, readable, and protected getter.
But there are times when you want an explicit backing field:
private bool? _isBlah;
public bool IsBlah
{
get
{
if (_isBlah == null)
{
// Do something expensive here and set _isBlah
_isBlah = true;
}
return _isBlah;
}
}
As far as I can remember, I have always managed my list properties from within my object, making them readonly.
private IList<DateTime> _dates;
public MyClass() {
_dates = new List<DateTime>();
}
public IList<DateTime> Dates {
get {
return _dates;
}
}
By doing so, I assure that my list is never null when I access it, since the client cannot assign it.
However, for your example, you only need to use the former approach if you need some kind of logic when getting or setting a property. Otherwise, automatic properties does exactly the same you would, only getting and setting a value to a private field. Furthermore, the { get; set; }
improves readability and helps other programmers understand your intention, in my humble point of view.
For instance:
public class MyClass {
private IList<DateTime> _dates;
public IList<DateTime> Dates {
get {
return _dates;
} set {
_dates = value;
}
}
}
versus
public class MyClasse {
public IList<DateTime> Dates { get; set; }
}
The second way makes it leaner and swifter, at least to me, what the intention is. And it becomes faster to code a class, when no logic inside the getter and setter is necessary.
Otherwise, one is not better than the other and does quite the same, speaking of getting and setting simply the property's value with no logic.
Most importantly, you need to be comfortable with your code. If it ends for you not getting any improvements, and you like what you're doing, than just do it. =)
I personally prefer the first method as it allows you to perform a few operations prior to the return.
E.G. (A really poor example)
private int _limit;
private int _onHand;
private bool returnToVendor;
public Item(int limit, int onHand)
{
_limit = limit;
_onHand = onHand;
}
public int ReturnStock
{
get
{
if(_onHand > _limit)
{
returnToVendor = true;
return _onHand;
}
}
set
{
_onHand = value;
if(_onHand < _limit)
{
returnToVendor = false;
}
}
}
The former is the original approach, the latter is an example of the newer 'auto properties' facility whereby the compiler generates a backing field for you automatically.
Some people (myself included) shy away from auto properties because the syntax is easy to mistake for abstract properties, there is no facility for 'readonly' properties and the syntax for auto properties with private setters is clumsy:
public List Dates
{
get;
private set;
}
I also find it uncomfortable to have my classes' internal implementation accessing fields via the class API.
The second variation is know as auto-implemented properties and was introduced in C#3.0 (hence why you may not have encountered it before).
It is preferable to use this format if you want to create simple properties with backing-fields and don't need to implement any logic in the 'getter' and 'setter'. Not only is it more concise, but it also forces you to access the property directly, rather than going through the backing field, which is normally best practice.
Note you can still initialise properties, you just do it via the constructor.
public class MyClass
{
public List<Date> Dates
{
get;
set;
}
public MyClass()
{
Dates = new List<Date>();
}
}