Подтвердить что ты не робот

Является ли хорошей практикой создание одноразовых переменных?

Мой коллега реорганизовал этот код:

private void btnGeneral_Click(object sender, RoutedEventArgs e)
{
    Button button = (Button)e.OriginalSource;
    Type type = this.GetType();
    Assembly assembly = type.Assembly;
    string userControlFullName = String.Format("{0}.{1}", type.Namespace, button.Name);
    UserControl userControl = (UserControl)assembly.CreateInstance(userControlFullName);
}

к этому коду:

private void btnGeneral_Click(object sender, RoutedEventArgs e)
{
    Button button = (Button)e.OriginalSource;
    Type type = this.GetType();
    Assembly assembly = type.Assembly;
    UserControl userControl = (UserControl)assembly.CreateInstance(String.Format("{0}.{1}", type.Namespace, button.Name));
}

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

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

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

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

Может ли кто-нибудь подумать о любых ситуациях, в которых нельзя создавать одноразовые имена переменных?

4b9b3361

Ответ 1

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

Но я бы не требовал "всегда использовать одноразовые переменные". Пример:

String name = "John";
person.setName(name);

не требуется, потому что

person.setName("John");

читается одинаково хорошо - если не лучше. Но, конечно, не все случаи столь же четкие. "Чтение" - это субъективный термин, в конце концов.

Ответ 2

Все ваши причины кажутся мне действительными.

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

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

Ответ 3

Ваш коллега не кажется последовательным.

Согласованное решение выглядит следующим образом:

private void btnGeneral_Click(object sender, RoutedEventArgs e)
{
    UserControl userControl = ((UserControl)type.Assembly).CreateInstance(String.Format("{0}.{1}", this.GetType().Namespace, ((Button)e.OriginalSource).Name));
}

Ответ 4

Я полностью с вами на этом.

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

public void OpenDocument(string filename, bool asReadonly, bool copyLocal, bool somethingElse)

Для меня это более читаемо:

bool asReadonly = true;
bool copyLocal = false;
bool somethingElse = true;

OpenDocument("somefile.txt", asReadonly, copyLocal, somethingElse);

.. чем:

OpenDocument("somefile.txt", true, false, true);

Ответ 5

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

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

GetCustomer(). GetOrders(). Итератор(). Далее(). GetItems(). Итератор(). Следующий(). GetProduct(). GetName()

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

Ответ 6

Оба кода одинаковы. Разумеется, ваш читатель более читабельен, универсален и отлаживаем, но, если бы это было так, то ваш кодекс не был бы меньше, чем потребитель.

Ответ 7

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

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

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

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

Ответ 8

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

for (int i1 = 0; i1 < BIG_NR; i1++)
{
  for (int i2 = 0; i2 < BIG_NR; i2++)
  {
    for (int i3 = 0; i3 < BIG_NR; i3++)
    {
      for (int i4 = 0; i4 < BIG_NR; i4++)
      {
        int amount = a + b;
        someVar[i1][i2][i3][i4] = amount;
      }
    }
  }
}

... дополнительное назначение может иметь слишком большое влияние на производительность. Но в целом ваши аргументы на 100% правильны.

Ответ 9

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

Это лучший аргумент против того, что я могу придумать!: -)

Ответ 10

Создание новой переменной означает еще одну концепцию, которую читатель должен отслеживать. (Рассмотрим крайний случай: int b = a; c = b;) Если метод настолько сложный - при такой необходимости разрушения - что дополнительная концепция - это цена, которую стоит заплатить, тогда вы должны пройти весь свиньи и расколоть это два метода. Таким образом вы получаете как значимое имя, так и меньший размер. (Меньше для вашего оригинального метода: если это так, как вы говорите, тогда людям обычно не нужно читать вспомогательный метод.)

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

Ответ 11

Я полностью со своим коллегой в принципе, но не в этом случае.

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

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

Ответ 12

Я согласен с большинством здесь, читаемость кода является ключевым.

Это редкий счетчик строк, который на самом деле пишет хорошо читаемый, очень удобный код.

Кроме того, все это скомпилируется в MSIL, и компилятор будет много оптимизировать для вас.

В следующем примере компилятор все равно будет оптимизировать код:

List<string> someStrings = new List<string>();
for (int i = 0; i < 1000; i++)
{
    string localString = string.Format("prefix{0}", i);
    someStrings.Add(localString);
}

Вместо

List<string> someStrings = new List<string>();
string localString = string.Empty;
for (int i = 0; i < 1000; i++)
{
    localString = string.Format("prefix{0}", i);
    someStrings.Add(localString);
}

Таким образом, в большинстве случаев нет причин для повышения производительности.

Ответ 13

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

Ответ 14

Согласовано

"упрощает чтение кода, т.е. больше вашего кода" читается как английский "

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

В конце концов, все мы знаем, что код труднее читать, чем писать.

Карл