views:

21014

answers:

11

How do you give a C# Auto-Property a default value? I either use the constructor, or revert to the old syntax.

Using the Constructor:

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

Using normal property syntax (with a default value)

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

Is there a better way?

A: 

Have you tried using the DefaultValueAttribute or ShouldSerialize and Reset methods in conjunction with the constructor? I feel like one of these two methods is necessary if you're making a class that might show up on the designer surface or in a property grid.

OwenP
No, those only work in the designer, not in "real life".
Hans Kesting
+52  A: 

To give auto implemented properties a default value, you'd have to do it in the constructor.

Darren Kopp
+15  A: 

DefaultValueAttribute ONLY work in the vs designer. It will not initialize the property to that value.

Darren Kopp
+1: [DefaultValue] is used to tell the designed what the default value is. If, in the properties window, you set the value to this default, then the value is not written to the generated code. Similarly, non-default values are shown in bold in the properties window. Of course, this only works if [DefaultValue] actually has the correct value. It does nothing to enforce this.
Roger Lipscombe
+7  A: 

Sometimes I use this, if I don't want it to be actually set and persisted in my db:

class Person
{
    private string _name; 
    public string Name 
    { 
        get 
        {
            return string.IsNullOrEmpty(_name) ? "Default Name" : _name;
        } 

        set { _name = value; } 
    }
}

Obviously if it's not a string then I might make the object nullable ( double?, int? ) and check if it's null, return a default, or return the value it's set to.

Then I can make a check in my repository to see if it's my default and not persist, or make a backdoor check in to see the true status of the backing value, before saving.

Hope that helps!

crucible
`return _name ?? "Default Name";` probably even is more clear that your
abatishchev
A: 

Personally, I don't see the point of making it a property at all if you're not going to do anything at all beyond the auto-property. Just leave it as a field. The encapsulation benefit for these item are just red herrings, because there's nothing behind them to encapsulate. If you ever need to change the underlying implementation you're still free to refactor them as properties without breaking any dependent code.

Hmm... maybe this will be the subject of it's own question later

Joel Coehoorn
You cannot refactor a field into an auto property without breaking the calling code. It might look the same same but the generated code is different. With auto properties the calling code calls get_propname and set_propname behind the covers, whereas it just access the field directly if it's a field.
David Reis
Yes, this is very old- I've since revised my position: http://stackoverflow.com/questions/205568/have-trivial-properties-ever-saved-your-bacon
Joel Coehoorn
You cannot access a field across AppDomain boundaries, either -- only a property or method.
Jacob
+1  A: 

@Joel: data binding and other reflection-based tools often expect properties rather than fields.

Chris Farmer
+10  A: 

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

I would argue that this syntax is best practice:

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 more clear control of the order values are assigned.

Keith
+1  A: 

You should not add a default to the constructor; this will mean that in the creation of the object the property will have to be assigned to twice (once as null, then again in the constructor). If you require a default value for a property it should broken out as a normal property (or possibly deferred to a builder in a creational pattern).

One other option is to do what ASP.Net does and define defaults via an attribute:

http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx

But again, I would simply break out the property as this is the clearest and most efficient option.

Lex
A: 
class Person 
{ 
    private string _name;  

    [DefaultValue(true)]  
    public string Name  
    {  
        get  { return _name; }     
        set { _name = value; }  
    } 
}
kkora
As stated in the documentation (http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx) the DefaultValueAttribute "will not cause a member to be automatically initialized with the attribute's value"
emddudley
A: 

little complete sample:

private bool bShowGroup ;
[Description("Show the group table"), Category("Sea"),DefaultValue(true)]
public bool ShowGroup
{
    get { return bShowGroup; }
    set { bShowGroup = value; }
}
ghiboz
Must add "System.ComponentModel" to the uses for this to work.
Cipi
A: 

[DefaultValue(true)]
dit not fill the property

kinki