В чем разница между этим:
public class Foo {
private Bar bar;
public Foo() { bar = new Bar(); }
}
и это:
public class Foo {
private Bar bar = new Bar();
public Foo() { }
}
В чем разница между этим:
public class Foo {
private Bar bar;
public Foo() { bar = new Bar(); }
}
и это:
public class Foo {
private Bar bar = new Bar();
public Foo() { }
}
Разница в том, что во втором случае инициализация поля происходит перед конструктором this/base, а в первом случае инициализация происходит внутри конструктора.
Bar
я использовал какой-то контекст данных (например, из структуры сущностей), есть ли практическая разница?
- person guhou; 01.08.2010
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 вызывается потом. Это редко имеет значение, если только поле не унаследовано и конструктор базового класса что-то с ним делает.
Или, если инициализаторы полей зависят друг от друга, они инициализируются в строгом текстовом порядке. Вы можете управлять порядком, делая это явно в конструкторе.
Немного констатируя очевидное, но со вторым подходом нет необходимости в конструкторе.
Разницы нет, потому что компилятор помещает все определения полей перед кодом конструктора. Так что в IL-коде оба варианта выглядят одинаково.
Чтобы добавить к ответу Дарина Димитрова, инициализация полей в строке - хорошая идея, если у вас есть несколько перегрузок конструктора, и вы по какой-то причине не хотите вызывать другие перегруженные конструкторы.