С точки зрения производительности реальной разницы нет; инициализаторы полей реализованы как логика конструктора. Единственное отличие состоит в том, что инициализаторы полей происходят перед любым конструктором "base" / "this".
Подход конструктора может использоваться с автоматически реализуемыми свойствами (инициализаторы полей не могут) - т.е.
[DefaultValue("")]
public string Foo {get;set;}
public Bar() { // ctor
Foo = "";
}
Кроме этого, я предпочитаю использовать синтаксис инициализатора поля; Я нахожу, что это держит вещи локализованными - то есть
private readonly List<SomeClass> items = new List<SomeClass>();
public List<SomeClass> Items {get {return items;}}
Мне не нужно охотиться вверх и вниз, чтобы найти, где это назначено ...
Очевидным исключением является ситуация, когда вам нужно выполнить сложную логику или иметь дело с параметрами конструктора - в этом случае инициализация на основе конструктора - это путь. Аналогично, если у вас есть несколько конструкторов, было бы предпочтительно, чтобы поля всегда устанавливались одинаково - поэтому у вас могут быть такие векторы, как:
public Bar() : this("") {}
public Bar(string foo) {Foo = foo;}
edit: в качестве дополнительного комментария обратите внимание, что в приведенном выше примере, если есть другие поля (не показаны) с инициализаторами полей, они непосредственно инициализируются только в конструкторах, которые вызывают base(...)
- т.е. , Другой конструктор не запускает инициализаторы полей, так как знает, что они выполняются this(...)
ctor.