Categories
automatic-properties c# constructor getter setter

What is the best way to give a C# auto-property an initial value?

2226

How do you give a C# auto-property an initial value?

I either use the constructor, or revert to the old syntax.

Using the Constructor:

class Person 
{
    public Person()
    {
        Name = "Initial Name";
    }
    public string Name { get; set; }
}

Using normal property syntax (with an initial value)

private string name = "Initial Name";
public string Name 
{
    get 
    {
        return name;
    }
    set
    {
        name = value;
    }
}

Is there a better way?

0

    2833

    In C# 5 and earlier, to give auto implemented properties an initial value, you have to do it in a constructor.

    Since C# 6.0, you can specify initial value in-line. The syntax is:

    public int X { get; set; } = x; // C# 6 or higher
    

    DefaultValueAttribute is intended to be used by the VS designer (or any other consumer) to specify a default value, not an initial value. (Even if in designed object, initial value is the default value).

    At compile time DefaultValueAttribute will not impact the generated IL and it will not be read to initialize the property to that value (see DefaultValue attribute is not working with my Auto Property).

    Example of attributes that impact the IL are ThreadStaticAttribute, CallerMemberNameAttribute, …

    1

    • 2

      It’s worth to note that this works also for getter-only properties: public int X { get; } = x;

      Feb 20 at 18:25

    323

    Edited on 1/2/15

    C# 6 :

    With C# 6 you can initialize auto-properties directly (finally!), there are now other answers that describe that.

    C# 5 and below:

    Though the intended use of the attribute is not to actually set the values of the properties, you can use reflection to always set them anyway…

    public class DefaultValuesTest
    {    
        public DefaultValuesTest()
        {               
            foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(this))
            {
                DefaultValueAttribute myAttribute = (DefaultValueAttribute)property.Attributes[typeof(DefaultValueAttribute)];
    
                if (myAttribute != null)
                {
                    property.SetValue(this, myAttribute.Value);
                }
            }
        }
    
        public void DoTest()
        {
            var db = DefaultValueBool;
            var ds = DefaultValueString;
            var di = DefaultValueInt;
        }
    
    
        [System.ComponentModel.DefaultValue(true)]
        public bool DefaultValueBool { get; set; }
    
        [System.ComponentModel.DefaultValue("Good")]
        public string DefaultValueString { get; set; }
    
        [System.ComponentModel.DefaultValue(27)]
        public int DefaultValueInt { get; set; }
    }
    

    1

    • Voting -1: At best, it looks subjectively looks a little neater than initializing in the constructor. This comes at the cost of confusing developers new to the codebase, worse performance, semantically changing the meaning of a built in attribute, only allowing constants, default values being hard to spot among multiple attributes, having to remember to run this in every constructor overload, and having the possibility of having default values defined in both the attribute and the constructor.

      – Jason

      Jul 5 at 18:32

    202

    When you inline an initial value for a variable it will be done implicitly in the constructor anyway.

    I would argue that this syntax was best practice in C# up to 5:

    class Person 
    {
        public Person()
        {
            //do anything before variable assignment
    
            //assign initial values
            Name = "Default Name";
    
            //do anything after variable assignment
        }
        public string Name { get; set; }
    }
    

    As this gives you clear control of the order values are assigned.

    As of C#6 there is a new way:

    public string Name { get; set; } = "Default Name";
    

    0