Инициализировать поля класса в конструкторе или при объявлении? - PullRequest
377 голосов
/ 23 августа 2008

Я недавно программировал на 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()
    {
        // .....
    }
}

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

Ответы [ 14 ]

2 голосов
/ 14 мая 2017

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

Существует также вопрос согласованности со статической инициализацией поля, которая должна быть встроенной для лучшей производительности. Руководство по проектированию фреймворка для Конструктор конструкторов произнесите это:

✓ СЧИТАЙТЕ инициализацию статических полей встроенными, а не явно используя статические конструкторы, поскольку среда выполнения способна оптимизировать производительность типов, которые не имеют явно определенного статического конструктора.

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

1 голос
/ 29 августа 2008

Установка значения в объявлении имеет небольшое преимущество в производительности. Если вы установите его в конструкторе, он будет установлен дважды (сначала на значение по умолчанию, затем сбрасывается в ctor).

0 голосов
/ 08 июля 2018

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

class MyGeneric<T>
{
    T data;
    //T data = ""; // <-- ERROR
    //T data = 0; // <-- ERROR
    //T data = null; // <-- ERROR        

    public MyGeneric()
    {
        // All of the above errors would be errors here in constructor as well
    }
}

И специальный метод для инициализации родового поля значением по умолчанию следующий:

class MyGeneric<T>
{
    T data = default(T);

    public MyGeneric()
    {           
        // The same method can be used here in constructor
    }
}
0 голосов
/ 24 августа 2008

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

Если значение, которое вы собираетесь присвоить переменной экземпляра, не зависит от каких-либо параметров, которые вы собираетесь передать конструктору, тогда присвойте его во время объявления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...