216

I'm used to writing classes like this:

public class foo {
  private string mBar = "bar";
  public string Bar {
    get { return mBar; }
    set { mBar = value; }
  }
  //... other methods, no constructor ...
}

Converting Bar to an auto-property seems convenient and concise, but how can I retain the initialization without adding a constructor and putting the initialization in there?

public class foo2theRevengeOfFoo {
  //private string mBar = "bar";
  public string Bar { get; set; }
  //... other methods, no constructor ...
  //behavior has changed.
}

You could see that adding a constructor isn't inline with the effort savings I'm supposed to be getting from auto-properties.

Something like this would make more sense to me:

public string Bar { get; set; } = "bar";
dlamblin
  • 43,965
  • 20
  • 101
  • 140
  • 2
    Is there a particular reason you don't want to do it in a constructor as it seems the natural place to me. – Garry Shutler Oct 03 '08 at 23:01
  • 15
    Only because I didn't have to do it in a constructor before. Therefore it's not saving me any effort if I have to add a constructor. – dlamblin Oct 03 '08 at 23:04
  • 6
    What if it were STATIC private string ...? Then you don't want to init within the constructor as it will be called every time a new object is created and that's specifically not want's wanted. ~~~ – Steve Pitchers Nov 23 '11 at 12:05
  • 5
    the question is a bit old, but to reply to @StevePitchers and dlamblin, you can create a static constructor to initialize your static properties only once... – Melvyn Jul 24 '13 at 18:41
  • @GarryShutler, I found a valid reason for not wanting to initialize a property in the constructor: if the property is marked as `virtual` and is overridden in a derived class, it's likely that it requires different initialization logic. Because the initialization code in the base constructor calls the property setter instead of setting the backing field directly, the derived class has to avoid that `base()` constructor in order to avoid triggering the default initialization logic. Seems like a slippery slope. – Steven Liekens May 21 '14 at 16:46

4 Answers4

256

Update - the answer below was written before C# 6 came along. In C# 6 you can write:

public class Foo
{
    public string Bar { get; set; } = "bar";
}

You can also write read-only automatically-implemented properties, which are only writable in the constructor (but can also be given a default initial value):

public class Foo
{
    public string Bar { get; }

    public Foo(string bar)
    {
        Bar = bar;
    }
}

It's unfortunate that there's no way of doing this right now. You have to set the value in the constructor. (Using constructor chaining can help to avoid duplication.)

Automatically implemented properties are handy right now, but could certainly be nicer. I don't find myself wanting this sort of initialization as often as a read-only automatically implemented property which could only be set in the constructor and would be backed by a read-only field.

This hasn't happened up until and including C# 5, but is being planned for C# 6 - both in terms of allowing initialization at the point of declaration, and allowing for read-only automatically implemented properties to be initialized in a constructor body.

Pang
  • 9,564
  • 146
  • 81
  • 122
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 33
    This is one of those places where the VB.NET team got it right - in VB you can declare your property and set it in the same line like this: `Public Property MyProp As String = "asdf"`. Unfortunately, you can't declare a public getter and a private setter like you can in C#. Not sure why neither team could manage to implement this feature properly. – mattmc3 Mar 14 '11 at 00:50
  • 5
    @mattmc3: They got it almost right. For some reason, they don't allow initialized readonly auto-properties, even though semantically they would make even more sense than initialized read-write properties. – supercat Dec 19 '11 at 19:45
  • 14
    "Jon Skeet has already written a book about C# 5.0; it’s currently sealed up. In three years, Anders Hejlsberg is going to open the book to see if the language design team got it right." http://meta.stackexchange.com/a/9174 – Dmitry Fedorkov Jul 09 '13 at 12:20
  • Update when future support is confirmed. – dlamblin Sep 05 '14 at 20:06
  • Jon, can you update your answer so it reflects how this works in C# 6 now? – poke Oct 21 '15 at 10:13
  • 5
    @poke: Done... although I don't intend to update *all* my answers like this :) – Jon Skeet Oct 21 '15 at 12:09
  • It was helpful for me. I was refactoring some code and was surprised when it compiled fine when I set a value to a read-only property in the constructor. Yay, C# 6. – Onots Jan 29 '16 at 08:06
  • 1
    Resharper suggested this for me. I said, sure, move it to the initializer and then I couldn't find it. Hehe. #programmerproblems – Yatrix Mar 18 '16 at 21:07
36

You can do it via the constructor of your class:

public class foo {
  public foo(){
    Bar = "bar";
  }
  public string Bar {get;set;}
}

If you've got another constructor (ie, one that takes paramters) or a bunch of constructors you can always have this (called constructor chaining):

public class foo {
  private foo(){
    Bar = "bar";
    Baz = "baz";
  }
  public foo(int something) : this(){
    //do specialized initialization here
    Baz = string.Format("{0}Baz", something);
  }
  public string Bar {get; set;}
  public string Baz {get; set;}
}

If you always chain a call to the default constructor you can have all default property initialization set there. When chaining, the chained constructor will be called before the calling constructor so that your more specialized constructors will be able to set different defaults as applicable.

joshperry
  • 41,167
  • 16
  • 88
  • 103
Aaron Powell
  • 24,927
  • 18
  • 98
  • 150
  • 1
    Hmm I guess I really showed 3 ways didn't I... :P – Aaron Powell Oct 03 '08 at 23:09
  • the last example is a bit misleading in that inline initialization results in the variables being initialized before other constructor logic. Your pattern results in the initialization happening after normal constructor logic (at least in example 3, for the int something constructor). – Eric Schoonover Oct 03 '08 at 23:14
  • I was working off the presumption that Bar was only to be initialised not utilised by the constructor, so its point of initialisation is irrelivant in the overall construction process – Aaron Powell Oct 03 '08 at 23:19
  • Personally, I find myself using it the other way normally, ie. the generic one calls the specialised one with some default parameters and does nothing itself. In this case, order of calling isn't really important. – Matthew Scharley Oct 04 '08 at 08:09
  • 62
    DefaultValueAttribute does NOT set the value of a property. All it does is tell Visual Studio what the default value should be, so that in the Property Window, the will be bolded if it is not set to that value. It does not change the value in any way. – James Curran Oct 04 '08 at 18:08
  • Correct James, but you could conciveably use reflection to read back the default property. It wouldn't be all that pretty but it'd be do-able – Aaron Powell Oct 05 '08 at 11:51
  • 10
    +1 James >> MSDN: "A DefaultValueAttribute will not cause a member to be automatically initialized with the attribute's value. You must set the initial value in your code." – Even Mien Sep 03 '09 at 20:16
  • Minor correction to the example; to call a constructor from the same class use: "this()" rather than "()" as shown. Helpful answer nonetheless. – codenheim Jul 21 '10 at 14:28
  • 6
    This answer really should be updated to remove the DefaultValue suggestion, as it will not work as shown. – ean5533 Mar 29 '13 at 21:22
31

This will be possible in C# 6.0:

public int Y { get; } = 2;
romanoza
  • 4,775
  • 3
  • 27
  • 44
3

In the default constructor (and any non-default ones if you have any too of course):

public foo() {
    Bar = "bar";
}

This is no less performant that your original code I believe, since this is what happens behind the scenes anyway.

Matthew Scharley
  • 127,823
  • 52
  • 194
  • 222
  • It's more work if you have multiple disparate constructors, compared to just initializing the underlying field and not using an automatic property - I don't really see what gain you get from the auto-property in that scenario... – Bittercoder Oct 04 '08 at 04:27
  • 2
    There is a difference, though: Initializing it right away means it's initialized even before the default constructor. I recently had an application where this actually mattered for some strange reason I don't understand. – Michael Klement Apr 30 '09 at 07:17