Определение / инициализация глобальных переменных: обычная практика? (Ориентирован на C #) - PullRequest
1 голос
/ 09 сентября 2010

Несколько дней назад я опубликовал похожий вопрос, но он был более ориентирован на любой файл * .Designer.cs. Этот вопрос направлен на объявление и инициализацию глобальных переменных в классе. Насколько мне известно, это почти обычная практика (кроме файлов * .Designer.cs, которые кажутся) помещать все глобальные переменные в начале определения класса, за которым следует остальная часть кода в любом порядке (я предпочитаю Getters and Setters затем Конструкторы, затем События, затем функции разного). Ну, я видел, как это было сделано, и сделал это сам, где глобальная переменная установлена ​​в объявлении.

И я не имею в виду:

ClassA clA = new ClassA();

Я имею в виду:

private int nViewMode = (int)Constants.ViewMode.Default;

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

Неправильный путь

private int nTotal = 100;
private int nCount = 10;
private int nDifference = nTotal - nCount;

Возможный правильный путь

private int nTotal = 100;
private int nCount = 10;
private int nDifference = 0;

void ClassConstructor()
{
  nDifference = nTotal - nCount;
}

Мои вопросы:

Что является наиболее распространенной / стандартной практикой в ​​такой ситуации? Какие плюсы и минусы того или другого? Эти вопросы актуальны только для некоторых языков, а не для других?

Мой последний вопрос, о котором я подумал, когда набирал это, и вот причина. В Visual Studio 2008 кажется, что я могу ставить точки останова в объявлениях глобальных переменных, в то время как я не думаю, что мог бы, когда я писал C ++ в колледже. Кроме того, я считаю, что в колледже нельзя использовать переменную, которая была объявлена ​​непосредственно перед текущей переменной, но опять же, это было в C ++. Поэтому я не уверен, что эти вопросы действительны только для продуктов MSVS (мы использовали Borland в колледже), новых компиляторов или нет. Если у кого-то есть понимание, оно ценится. Спасибо.

Ответы [ 4 ]

2 голосов
/ 09 сентября 2010

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

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

В случае nDifference, возможно, свойство, которое инкапсулирует логику, имело бы больше смысла, так:

  1. Если не используется, nDifference не нужно вычислять каждый раз, когда создается новый экземпляр класса.
  2. Указывает, что логика для nDifference всегда должна быть одинаковой, независимо откакой конструктор используется.
1 голос
/ 09 сентября 2010

Определение языка C # гарантирует, что инициализация полей будет происходить в текстовом порядке в каждой единице компиляции (файле). Это означает, что вполне нормально иметь сложные выражения в инициализаторе переменных объявлений статических полей. (С другой стороны, поля экземпляра не могут ссылаться на другие поля экземпляра.)

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

class Demo1 {
    static int x = y + 10;  // x == 10
    static int y = 5;
}

class Demo2 {
    static int y = 5;
    static int x = y + 10;  // x == 15
}

Как уже говорили другие, я бы предпочел, чтобы инициализаторы, общие для всех экземпляров (независимо от выбранного конструктора), встречались в объявлениях.

Такое поведение переупорядочения верно только для инициализаторов статических переменных. Инициализация констант происходит во время компиляции, и значения рассчитываются в порядке, обеспечивающем правильную инициализацию значений (а циклические ссылки на константы, в отличие от переменных, не допускаются).

class Demo3 {
    const int x = y + 10;  // Evaluated second. x == 15
    const int y = 5;       // Evaluated first.
}

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

class Demo4 {
    int y = 5;
    int x { get { return y + 10; } }
}
1 голос
/ 09 сентября 2010

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

Как уже говорили другие, тщательно продумайте свое соглашение и применяйте его последовательно.

1 голос
/ 09 сентября 2010

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

В более старых диалектах C # (мы все еще на 2.0, где я работаю), я предполагаю, что есть аргумент согласованности, если вы заполняете элемент Dictionary<T> или что-то в конструкторе, так как новый синтаксис инициализатора не сделалпокажусь позже.В этом случае вы можете сделать аргумент, что вы хотите сохранить все ваши инициализации вместе.Аналогичным образом, если вы инициализируете некоторые члены на основе аргументов конструктора, возможно, имеет больше смысла сохранять всю инициализацию вместе, а не присваивать какие-то вещи, где они объявлены, и другие вещи в конструкторе - но если у вас более одного конструктора, есливы не повторяете себя, вы просто в конечном итоге будете иметь некоторую инициализацию в одном месте, а остальные - в любом случае, так что вам, вероятно, лучше назначать вещи там, где вы их объявляете.

...