views:

100

answers:

5

I have read that there are good reasons to use properties instead of fields in c# on SO. So now I want to convert my code from using fields to using properties.

For an instance field of a class, I can set a default value. For example:

int speed = 100;

For the equivalent property, which I think is:

int Speed { get; set; }

My understanding is that the Speed property will be initialised to zero when the class is instantiated. I have been unable to find out how to set a default value to easily update my code. Is there an elegant way to provide a default value for a property?

It seems like there should be an elegant way to do this, without using a constructor, but I just can't find out how.

A: 

you must set the default value for the property in the constructor. There's no other way to do it besides this for automatic properties since the fields for the automatic props are declared at compile time and replaced within getter/setter. However in explicit properties, you can initialize the field the property uses to read or write as Joe mentioned in his answer.

this. __curious_geek
+6  A: 

Best bet is to do a normal old-fashioned field-backed property, like:

private int _speed = 100;
public int Speed { get { return _speed; } set { _speed = value; } }
Joe Enos
Thanks for the code. That is quite elegant and I don't have to use a constructor. Brilliant.
Jeremy Larter
No prob. This is what you'll see all the time for code written prior to .NET 3.0. With 3.0, the auto-property was introduced, but you run into exactly the problem you brought up, where you can't define a default value simply, without using the constructor.
Joe Enos
I still like the old way of doing properties, however it can cause confusion because you don't know which way to get/set the valueu from inside the class. Do you use the instance variable or do you use the property?
Jerod Houghtelling
@Jerod: If you use code profiling tools such as NCover, it will catch property accessors, not field assignment. Maybe this is marginally slower? Likely not noticeable. You definitely want to use property if you want to have any input validation or other cheap functional routines when getting/setting property. Sometimes I use a field backing two or more properties, but use type conversion on one. A private field of `List<string>`, and a property to get/set a `String[]` for example, but I can also have a get/set that takes `String` of CSV.
maxwellb
+1 for love of old-fashioned properties.
maxwellb
@maxwellb: You brought up using the property whenever there's input validation or similar when accessing the property - in my opinion, this is a good reason for simply always using the property. If you get used to using fields most of the time, you may simply forget to use a property at a time when there's a legitimate reason to. If you're used to using properties, then you'll never miss the important calls.
Joe Enos
Indeed. Indeed.
maxwellb
A: 

The constructor is the only way to set the initial value of an auto property.

Adam Robinson
A: 

CciSharp supports the DefaultValue attribute, which allows placing default values on auto properties. Whether CciSharp qualifies as an "elegant" solution, however, is a matter of opinion (it acts as a post-compiler that edits the IL in the binary).

Stephen Cleary
A: 

The design-pattern I use, which is used throughout Microsoft's Windows.Forms controls and other .NET Classes. Moreover, from my understanding, the initialization outside of the contructor allows just-in-time compiler to optimze the class code.

public class Foo {
    public static const int DefaultSpeed = 100;
    private int _speed = DefaultSpeed;
    [DefaultValue(DefaultSpeed)]
    public int Speed { get { return _speed; } set { _speed = value; } }
}

    public class Foo {
        public static Color DefaultForecolor { get {return SystemColors.WindowText; }}
        private Color _forecolor = DefaultForecolor;
        [DefaultValue(DefaultForeColor)]
        public Color Forecolor { get { return _forecolor; } set { _forecolor = value; } }
    }
AMissico