Инициализация авто-свойств С#

Я привык писать такие классы:

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

Преобразование Bar в авто-свойство кажется удобным и сжатым, но как сохранить инициализацию без добавления конструктора и размещения там инициализации?

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

Вы могли видеть, что добавление конструктора не является встроенным с экономией усилий, которую я должен получать от авто-свойств.

Что-то вроде этого будет иметь для меня больше смысла:

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

Ответ 1

Обновление - ответ ниже был написан до появления С# 6. В С# 6 вы можете написать:

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

Вы также можете писать автоматически обновляемые свойства только для чтения, которые записываются только в конструкторе (но также могут быть заданы начальное значение по умолчанию:

public class Foo
{
    public string Bar { get; }

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

Несчастливо, что нет никакого способа сделать это прямо сейчас. Вы должны установить значение в конструкторе. (Использование цепочки конструкторов может помочь избежать дублирования.)

Автоматически реализованные свойства удобны прямо сейчас, но, безусловно, могут быть приятнее. Я не считаю себя такой инициализацией столь же часто, как автоматически реализованное свойство только для чтения, которое может быть установлено только в конструкторе и будет поддерживаться только для чтения.

Это не произошло до и включая С# 5, но планировалось для С# 6 - как с точки зрения разрешения инициализации в точке объявления, так и для автоматического инициализации свойств, реализованных только для чтения, в конструкторе тела.

Ответ 2

Вы можете сделать это через конструктор своего класса:

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

Если у вас есть другой конструктор (т.е. тот, который принимает параметры) или кучу конструкторов, вы всегда можете получить это (называемое цепочкой конструкторов):

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;}
}

Если вы всегда связываете вызов с конструктором по умолчанию, вы можете установить всю инициализацию по умолчанию. При цепочке цепочный конструктор будет вызываться перед вызывающим конструктором, чтобы ваши более специализированные конструкторы могли устанавливать различные значения по умолчанию, если это применимо.

Ответ 3

Это будет возможно в С# 6.0:

public int Y { get; } = 2;

Ответ 4

В конструкторе по умолчанию (и любых нестандартных, если у вас тоже есть):

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

Это не менее впечатляет, чем ваш исходный код, я считаю, так как это то, что происходит за кулисами. В любом случае.