Возможный дубликат:
Лучшая практика: инициализировать поля класса в конструкторе или объявлении?
Я работаю с С#, но это, вероятно, относится к Java (или любому другому языку, который также допускает это поведение)...
Какой способ предпочтительнее/лучше? Предположим, что ВСЕГДА понадобится _memberVar
1.
class MyClass
{
private Dictionary<int, string> _memberVar = new Dictionary<int, string>();
public MyClass() {}
}
- ИЛИ -
2.
class MyClass
{
private Dictionary<int, string> _memberVar = null
public MyClass()
{
_memberVar = new Dictionary<int, string>();
}
}
Теперь скажем, что MyClass
имеет более 10 конструкторов... Поэтому я не хочу иметь _memberVar = new Dictionary<int, string>();
во всех этих конструкторах lol. Что-то не так с 1-м способом? Благодаря
Edit: Я понимаю, что я могу связать конструкторы, но это довольно сложный класс... некоторые конструкторы называют базу, некоторые называют другие конструкторы уже и т.д. И т.д.
Вам не нужно инициализировать переменные-члены, но это не повредит, если вы это сделаете. Пользовательские переменные автоматически получают значения по умолчанию, обычно null
для объектов и значение по умолчанию для примитивных типов (например, 0
для int
).
Что касается наличия разных конструкторов, вам не нужно повторять инициализацию члена в каждой версии, так как вы можете вызвать перегруженный конструктор из любого другого, как и с перегруженным методом.
Что касается лучшей практики, лично, я инициализирую переменные-члены в конструкторе, так как здесь я хочу "сконструировать" мой объект в стабильном состоянии. Другими словами, даже если бы у меня были инициализированные переменные-члены, где я объявляю их, когда вызывается конструктор, это было бы так, как если бы я очищал шифер.
В отношении _memberVar инициализируется в 10 конструкторах: я думаю, вам нужно переосмыслить свой класс. Это звучит чрезмерно. Если вы выполняете одну и ту же работу в каждом конструкторе, вы нарушаете DRY. Вместо этого попробуйте принять эту структуру:
public class MyClass {
Foo _foo;
Bar _bar;
Baz _baz;
public MyClass(Foo foo, Bar bar, Baz baz) {
_foo = foo; _bar = bar; _baz = baz;
}
public MyClass(Foo foo, Bar bar) : this(foo, bar, new Baz()) { }
public MyClass(Foo foo) : this(foo, new Bar()) { }
public MyClass() : this(new Foo()) { }
}
Обратите внимание, что я намеренно не вызывал в самом широком конструкторе в каждом из остальных, а вместо этого каскадировался так, чтобы наследовать поведение, если смысл значений по умолчанию изменился для каждого.
Что касается инициализации члена при объявлении, если элемент не сконструирован с использованием одного из аргументов конструктору, я предпочитаю инициализировать его при объявлении.
Первый метод - это то, как я обычно это делаю, и вполне приемлемо, если все ваши конструкторы инициализируют его с тем же значением. Я определенно предпочитаю его также для статических переменных, чтобы избежать явного объявления статического конструктора.
В идеале для этого вам следует использовать инъекцию зависимостей. Это означает, что вы оставите его в экземпляре своего класса, чтобы создавать новые экземпляры зависимостей и вводить их в новый экземпляр класса, а не создавать класс самими зависимостями.
Dictionary
, поэтому я бы предположил, что это конечный объект в конце графа объектов, и в этом случае текущий объект будет отвечать за его создание.