Bezdepbonusu7Программирование: статьи и ответы

Вопрос

В чем разница между созданием экземпляра в конструкторе или в определении поля?

Автор вопроса: guhouОтветов: 5

В чем разница между этим:

public class Foo {
    private Bar bar;
    public Foo() { bar = new Bar(); }
}

и это:

public class Foo {
    private Bar bar = new Bar();
    public Foo() { }
}
  • stackoverflow.com/questions/24551/ SwDevMan81 01.08.2010
  • stackoverflow.com/questions/1157201/ SwDevMan81 01.08.2010

constructor

Ответы

Ответ 1 · рейтинг 9 · Darin Dimitrov

Разница в том, что во втором случае инициализация поля происходит перед конструктором this/base, а в первом случае инициализация происходит внутри конструктора.

Ответ 2 · рейтинг 6 · Hans Passant

CLR не поддерживает такие поля инициализации. Чтобы заставить его работать, компилятор C# переписывает ваш конструктор. Ил выглядит так:

  IL_0000:  ldarg.0
  IL_0001:  newobj     instance void ConsoleApplication1.Bar::.ctor()
  IL_0006:  stfld      class ConsoleApplication1.Bar ConsoleApplication1.Foo::bar
  IL_000b:  ldarg.0
  IL_000c:  call       instance void [mscorlib]System.Object::.ctor()
  IL_0011:  ret

Обратите внимание, что конструктор Bar вызывается перед базовым конструктором Foo. В чем разница с вашим другим фрагментом, там базовый конструктор Foo вызывается потом. Это редко имеет значение, если только поле не унаследовано и конструктор базового класса что-то с ним делает.

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

Ответ 3 · рейтинг 1 · John Parker

Немного констатируя очевидное, но со вторым подходом нет необходимости в конструкторе.

Ответ 4 · Coderik

Разницы нет, потому что компилятор помещает все определения полей перед кодом конструктора. Так что в IL-коде оба варианта выглядят одинаково.

Ответ 5 · Keith Paul Barrow

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы