Es gibt einige (recht seltene) Fälle, in denen das Risiko besteht, dass:
Wiederverwendung einer Variablen, die nicht wiederverwendet werden soll (siehe Beispiel 1),
oder Verwenden einer Variablen anstelle einer anderen, semantisch nah (siehe Beispiel 2).
Beispiel 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`.
}
Beispiel 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.
Dieses Risiko kann durch die Einführung eines Anwendungsbereichs gemindert werden:
Beispiel 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.
Beispiel 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`.
}
Sieht es falsch aus Würden Sie eine solche Syntax vermeiden? Ist es für Anfänger schwer zu verstehen?
c#
coding-style
language-features
scope
Arseni Mourzenko
quelle
quelle
Antworten:
Wenn Ihre Funktion so lang ist, dass Sie keine unerwünschten Nebenwirkungen oder illegalen Wiederverwendungen von Variablen mehr erkennen können, ist es an der Zeit, sie in kleinere Funktionen aufzuteilen - was einen internen Bereich sinnlos macht.
Um dies durch einige persönliche Erfahrungen zu belegen: Vor einigen Jahren habe ich ein C ++ - Legacy-Projekt mit ~ 150.000 Codezeilen geerbt, das einige Methoden enthielt, die genau diese Technik verwendeten. Und raten Sie mal - all diese Methoden waren zu lang. Da wir den größten Teil dieses Codes überarbeitet haben, wurden die Methoden immer kleiner, und ich bin mir ziemlich sicher, dass es keine verbleibenden "internen Bereichs" -Methoden mehr gibt. Sie werden einfach nicht benötigt.
quelle
Für Anfänger (und jeden Programmierer) ist es viel einfacher, an Folgendes zu denken:
als zu denken:
Darüber hinaus spielen solche Blöcke aus Lesersicht keine offensichtliche Rolle: Das Entfernen hat keine Auswirkungen auf die Ausführung. Der Leser kann sich am Kopf kratzen und versuchen zu erraten, was der Codierer erreichen wollte.
quelle
Die Verwendung eines Oszilloskops ist technisch richtig. Wenn Sie Ihren Code jedoch lesbarer machen möchten, sollten Sie diesen Teil in einer anderen Methode extrahieren und ihm einen vollständigen Namen geben. Auf diese Weise können Sie einen Bereich Ihrer Variablen und auch einen Namen für Ihre Aufgabe angeben.
quelle
Ich bin damit einverstanden, dass die Wiederverwendung von Variablen häufig ein Codegeruch ist. Wahrscheinlich sollte ein solcher Code in kleineren, in sich geschlossenen Blöcken überarbeitet werden.
Es gibt ein bestimmtes Szenario, OTOH, in C #, in dem sie zum Popup neigen - nämlich bei Verwendung von Switch-Case-Konstrukten. Die Situation wird sehr gut erklärt in: C # Switch-Anweisung mit / ohne geschweifte Klammern… was ist der Unterschied?
quelle