Объявление переменной ближе к использование против объявления в верхней части способ


Как часть наших спринтов, мы сделаем рецензирование друг друга код.

Вот код, который я рассматриваю.

public void SendEmail()
{

    string emailAddress = string.Empty;
    string managerEmailAddress = string.Empty;

    if (//condition)
    {
        //do something
        //Retrieve emailAddress and managerEmailAddress
        EmailMessage.To = emailAddress;
        EmailMessage.CC = managerEmailAddress;
    }
}

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

Что вы думаете?



9722
8
c#
задан 25 ноября 2011 в 11:11 Источник Поделиться
Комментарии
6 ответов

Я согласен с Guffa и dreza, переменные должны быть объявлены только во внешней области, если это действительно необходимо, так как это сбивает с толку и может привести к ошибкам. Также, если метод является достаточно долго, что объявление переменной в верхней означает, что он не близко к его использование, то он, вероятно, может извлечь выгоду из оптимизации кода в отдельные методы. Это также поможет читабельности, потому что вы будете иметь имена способ объяснить, что происходит.

Некоторые примеры (цитаты, как это только мое мнение):

1: "Плохой" пример

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

string emailAddress = string.Empty;
string managerEmailAddress = string.Empty;

if (//condition)
{
emailAddress = Foo();
EmailMessage.To = emailAddress;
}
else
{
emailAddress = Bar();
// Do something different with emailAddress;
}

// No more usages of emailAddress

2: "улучшение" пример:

Это лучше, потому что эти переменные определены, где они используются, поэтому нет необходимости идти искать другие обычаи.

if (//condition)
{
var emailAddress = Foo();
EmailMessage.To = emailAddress;
}
else
{
var emailAddress = Bar();
// Do something different with emailAddress;
}

3: "даже лучше" пример:

Я думаю, что это лучшее, что может сделать, потому что имена методов поможет с пониманием кода.

if (//condition)
{
ExplanatoryName1(//pass anything in that is required);
}
else
{
ExplanatoryName2(//pass anything in that is required);
}

4: Если вам нужно вернуться из методов:

var methodReturn = condition ? ExplanatoryName1(args) : ExplanatoryName2(args);

5
ответ дан 25 ноября 2011 в 08:11 Источник Поделиться

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

//some code

//comment explaining what the following does:
{
string emailAddress = Foo();
EmailMessage.To = emailAddress;
}

//more code

//comment explaining what the following does:
{
string emailAddress = Boo();
SomeOtherEmailMessage.From = emailAddress;
}

//yet more code

Еще одно замечание: я вижу, что, когда ваш коллега объявил электронный адрес переменной, он назначил строку.Пусто к нему, и потом он вновь назначенные значимое значение для его перед использованием его. Некоторые люди считают, что при объявлении локальной переменной, вы всегда должны инициализировать его с некоторым начальным значением, и они следуют этому правилу в почти суеверный моды. Это неправильно. Это может быть целесообразно вернуться в те времена, когда все мы имели, был какой-то примитивный и сырой компиляторов C, но не больше. Современные компиляторы С, С++, C# и Java имеют довольно хорошее предупреждение, если переменная может быть читали, прежде чем он был инициализирован. Так, по предварительной инициализации переменной при объявлении времени, значение которой по определению бессмысленно, (т. к. значимое значение еще не известно на тот момент) обходится проверки безопасности вашего компилятора, и вы на самом деле открывая возможность ошибки: если вы забыли присвоить нужное значение в переменную и дальше вниз, прежде чем вы на самом деле использовать его, компилятор не предупредит вас, поскольку компилятор знает, переменная уже инициализирована при объявлении.

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

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

5
ответ дан 27 ноября 2011 в 09:11 Источник Поделиться

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

Однако я предпочитаю объявлять переменные как можно ближе к их первым использованием, насколько это возможно. Несколько причин.


  1. Я считаю, что переменная должна использоваться только одна вещь. Объявляя их близко к их использованию, то вы неявно заявив Это, где переменная используется.

  2. Легче увидеть, когда эта переменная используется в коде. Если вы метод несколько строк, то вы можете легко увидеть, где переменная используется.

  3. Это может помочь с определением рефакторинг кода. Например, путем добавления переменных в области видимости состояние выше вы можете прийти, чтобы решить, что на самом деле может быть сделано в другом месте.

4
ответ дан 25 ноября 2011 в 07:11 Источник Поделиться

Читать эффективная Java, второе издание, пункт 45: минимизировать область видимости локальных переменных. Он имеет хороший обзор по этой теме. (Google для "минимизации видимости локальных переменных", это в Google книгах тоже.)

3
ответ дан 25 ноября 2011 в 12:11 Источник Поделиться

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

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

Пример:

void DoSomething(bool write) {

string source = String.Empty;
string destination = String.Empty;
string data = String.Empty;

if (write) {
destination = "some other thing";
WriteTo(destination, data);
} else {
source = "something";
data = ReadFrom(destination); // oops, used the wrong variable
}

}

3
ответ дан 25 ноября 2011 в 02:11 Источник Поделиться

Прежде чем читать Чистый код Роберт С. Мартин, Я бы сказал, что вы должны пойти с вашим коллегой вариант (все переменные в верхней части), потому что это выглядит лучше/чище и разумнее (последнее почему-то приходит, без сомнения, от пары лет С/С++). В наше время, я обращаю внимание на область видимости переменной и практик чистого кода; так что версия, которой я хотел бы использовать это:

public void SendEmail()
{
if (//condition)
{
string emailAddress = GetEmailAddress();
EmailMessage.To = emailAddress;

string managerEmailAddress = GetManagerEmailAddress();
EmailMessage.CC = managerEmailAddress;
}
}

которые, в зависимости от остального кода, может быть улучшено ("экстракт до упаду").

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

public void SendEmail()
{
string emailAddress = string.Empty;
string managerEmailAddress = string.Empty;

if (//condition)
{
//do something
//Retrieve emailAddress and managerEmailAddress
EmailMessage.To = emailAddress;
EmailMessage.CC = managerEmailAddress;
}

EmailMessage.BCC = emailAddress;
}

...и рефакторинг один:

public void SendEmail()
{
if (//condition)
{
string emailAddress = GetEmailAddress();
EmailMessage.To = emailAddress;

string managerEmailAddress = GetManagerEmailAddress();
EmailMessage.CC = managerEmailAddress;
}

EmailMessage.BCC = emailAddress; //now what?
}

Так что, если вы рефакторинг кода, Вы должны держать глаза на сферу.

3
ответ дан 18 декабря 2013 в 11:12 Источник Поделиться