Я недавно программировал на C # и Java, и мне любопытно, где лучше всего инициализировать поля моего класса.
Должен ли я сделать это при объявлении?:
public class Dice
{
private int topFace = 1;
private Random myRand = new Random();
public void Roll()
{
// ......
}
}
или в конструкторе?:
public class Dice
{
private int topFace;
private Random myRand;
public Dice()
{
topFace = 1;
myRand = new Random();
}
public void Roll()
{
// .....
}
}
Мне действительно любопытно, что некоторые из вас, ветеранов, считают лучшей практикой , Я хочу быть последовательным и придерживаться одного подхода.
Мои правила:
null
, false
, 0
, 0.0
†¦). Семантика C# отличается немного от Java здесь. В присвоении C# в объявлении выполняется прежде, чем назвать конструктора суперкласса. В Java это сразу сделано, после которого позволяет 'этому' использоваться (особенно полезный для анонимных внутренних классов) и означает, что семантика двух форм действительно соответствует.
, Если Вы можете, сделайте полевой финал.
В C# это не имеет значения. Эти два примера кода, которые Вы даете, совершенно эквивалентны. В первом примере компилятор C# (или действительно ли это - CLR?) создаст пустого конструктора и инициализирует переменные, как будто они были в конструкторе (существует небольшой нюанс к этому, который Jon Skeet объясняет в комментариях ниже). Если уже будет конструктор тогда, то любая инициализация "выше" будет перемещена в вершину его.
С точки зрения лучшей практики первый менее подвержен ошибкам, чем последний, как кто-то мог легко добавить другого конструктора и забыть объединять ее в цепочку.
Принятие типа в Вашем примере, определенно предпочтите инициализировать поля в конструкторе. Исключительные случаи:
, я всегда думаю о списке полей наверху класса как оглавление (что содержится здесь, не, как это используется), и конструктор как введение. Методы, конечно, являются главами.
Что, если я сказал Вам, это зависит?
я в целом инициализирую все и делаю это последовательным способом. Да это чрезмерно явно, но также немного легче поддержать.
, Если мы волнуемся по поводу производительности, хорошо тогда, я инициализирую только, что должно быть сделано и поместить ее в области, которые она дает большей части удара для маркера.
В системе реального времени, я подвергаю сомнению, нужны ли мне даже переменное или постоянное вообще.
И в C++ я часто не делаю рядом ни с какой инициализацией ни в одном месте и перемещаю его в Init () функция. Почему? Ну, в C++, если Вы инициализируете что-то, что может выдать исключение во время объектной конструкции, которую Вы открываете сами для утечек памяти.
Существует небольшой выигрыш в производительности к устанавливанию значения в объявлении. При установке его в конструкторе, это на самом деле устанавливается дважды (сначала к значению по умолчанию, то сброшенный в ctor).
Я обычно сужу конструктора, чтобы сделать только получение зависимостей и инициализацию связанных членов экземпляра с ними. Это сделает Вас жизнью легче, если Вы захотите к модульному тесту свои классы.
, Если значение Вы собираетесь присвоить переменной экземпляра, не добирается под влиянием ни одного из параметров, которые Вы собираетесь передать Вам, конструктор тогда присваивает его во время объявления.
default(T)
всегда является значением, которое имеет внутреннее двоичное представление0
. – Olivier Jacot-Descombes 14.03.2013, 08:26