Членская инициализация переменной C#; лучшая практика?

92
задан Jonathan Leffler 27 May 2015 в 17:56
поделиться

5 ответов

С точки зрения производительности нет никакой реальной разницы; полевые инициализаторы реализованы как логика конструктора. Единственная разница - то, что полевые инициализаторы происходят перед любой "основой" / "этот" конструктор.

подход конструктора может использоваться с автореализованными свойствами (полевые инициализаторы не могут) - т.е.

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

я не должен отправляться на охоту вверх и вниз для нахождения, где это присвоено...

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

public Bar() : this("") {}
public Bar(string foo) {Foo = foo;}

редактирование: как комментарий стороны, обратите внимание, что в вышеупомянутом, если существуют другие поля (не показаны) с полевыми инициализаторами, то они только непосредственно инициализируются в конструкторах, которые звонят base(...) - т.е. public Bar(string foo) ctor. Другой конструктор делает не выполненные полевые инициализаторы, так как это знает, что они сделаны this(...) ctor.

77
ответ дан Marc Gravell 24 November 2019 в 06:34
поделиться

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

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

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

, С другой стороны, влияние производительности и код 'чрезмерное увеличение размера' обычно будут незначительны, и полевой синтаксис инициализатора обладает важным преимуществом уменьшения риска, что Вы могли бы забыть инициализировать некоторое поле в одном из Ваших конструкторов.

10
ответ дан Tor Haugen 24 November 2019 в 06:34
поделиться

Используйте или полевые инициализаторы или создайте Init () функция. Проблема с помещением этих вещей в Вашем конструкторе состоит в том, что, если когда-нибудь необходимо добавлять 2-го конструктора, Вы заканчиваете со скопировать/вставить кодом (или Вы пропускаете его и заканчиваете с неинициализированными переменными).

я или инициализировал бы, где объявлено. Или сделайте, чтобы конструктор (конструкторы) назвал Init () функцией.

2
ответ дан GeekyMonkey 24 November 2019 в 06:34
поделиться

Например, переменные, это - в основном вопрос стиля (я предпочитаю использовать конструктора). Для статических переменных, существует выигрыш в производительности к инициализации встроенного (не всегда возможен, конечно).

1
ответ дан Tim Cooper 24 November 2019 в 06:34
поделиться

Это действительно ваше дело.
я часто инициализирую их встроенный, вызываю, мне не нравится иметь конструктора, когда мне действительно не нужен один (мне нравятся маленькие классы!).

0
ответ дан Nico 24 November 2019 в 06:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: