В некоторых (довольно редких) случаях существует риск:
повторное использование переменной, которая не предназначена для повторного использования (см. пример 1),
или используя переменную вместо другой, семантически близко (см. пример 2).
Пример 1:
var data = this.InitializeData();
if (this.IsConsistent(data, this.state))
{
this.ETL.Process(data); // Alters original data in a way it couldn't be used any longer.
}
// ...
foreach (var flow in data.Flows)
{
// This shouldn't happen: given that ETL possibly altered the contents of `data`, it is
// not longer reliable to use `data.Flows`.
}
Пример 2:
var userSettingsFile = SettingsFiles.LoadForUser();
var appSettingsFile = SettingsFiles.LoadForApp();
if (someCondition)
{
userSettingsFile.Destroy();
}
userSettingsFile.ParseAndApply(); // There is a mistake here: `userSettingsFile` was maybe
// destroyed. It's `appSettingsFile` which should have
// been used instead.
Этот риск можно уменьшить, введя область действия:
Пример 1:
// There is no `foreach`, `if` or anything like this before `{`.
{
var data = this.InitializeData();
if (this.IsConsistent(data, this.state))
{
this.ETL.Process(data);
}
}
// ...
// A few lines later, we can't use `data.Flows`, because it doesn't exist in this scope.
Пример 2:
{
var userSettingsFile = SettingsFiles.LoadForUser();
if (someCondition)
{
userSettingsFile.Destroy();
}
}
{
var appSettingsFile = SettingsFiles.LoadForApp();
// `userSettingsFile` is out of scope. There is no risk to use it instead of
// `appSettingsFile`.
}
Это выглядит неправильно? Вы бы избежали такого синтаксиса? Сложно ли это понять начинающим?
c#
coding-style
language-features
scope
Арсений Мурзенко
источник
источник
Ответы:
Если ваша функция настолько длинна, что вы больше не можете распознать нежелательные побочные эффекты или незаконное повторное использование переменных, то пришло время разделить ее на более мелкие функции, что делает внутреннюю область бессмысленной.
Чтобы подкрепить это своим личным опытом: несколько лет назад я унаследовал унаследованный проект C ++ с ~ 150 тыс. Строк кода, и он содержал несколько методов, использующих именно эту технику. И угадайте, что - все эти методы были слишком длинными. Поскольку мы реорганизовали большую часть этого кода, методы стали все меньше и меньше, и я почти уверен, что больше не осталось методов "внутренней области видимости"; они просто не нужны.
источник
Начинающему (и любому программисту) гораздо проще думать о:
чем думать о:
Более того, с точки зрения читателя, такие блоки не играют очевидной роли: их удаление не влияет на выполнение. Читатель может почесать голову, пытаясь угадать, чего хотел добиться кодер.
источник
Использование области является технически правильным. Но если вы хотите сделать ваш код более читабельным, вы должны извлечь эту часть в другом методе и дать ему полное имя. Таким образом, вы можете указать область действия ваших переменных, а также указать имя вашей задачи.
источник
Я согласен, что повторное использование переменной чаще всего не пахнет кодом. Вероятно, такой код должен быть реорганизован в меньшие, автономные блоки.
Существует один конкретный сценарий, OTOH, в C #, когда они имеют тенденцию всплывать - это когда используются конструкции switch-case. Ситуация очень хорошо объяснена в: C # оператор Switch с / без фигурных скобок ... какая разница?
источник