2010-07-06 13 views
16

Manchmal verwende ich geschweifte Klammern, um einen Codeblock zu isolieren, um die spätere Verwendung einer Variablen aus Versehen zu vermeiden. Zum Beispiel, wenn ich mehrere SqlCommand s in der gleichen Methode setze, kopiere ich häufig Code-Blöcke, indem ich die Namen mische und zwei Befehle hintereinander ausführe. Das Hinzufügen von geschweiften Klammern hilft, diese Situation zu vermeiden, da die Verwendung eines falschen SqlCommand an einer falschen Stelle zu einem Fehler führt. Hier eine Abbildung:Ist es falsch, geschweifte Klammern für verschiedene Zwecke zu verwenden?

Collection<string> existingCategories = new Collection<string>(); 

// Here a beginning of a block 
{ 
    SqlCommand getCategories = new SqlCommand("select Title from Movie.Category where SourceId = @sourceId", sqlConnection, sqlTransaction); 
    getCategories.Parameters.AddWithValue("@sourceId", sourceId); 
    using (SqlDataReader categoriesReader = getCategories.ExecuteReader(System.Data.CommandBehavior.SingleResult)) 
    { 
     while (categoriesReader.Read()) 
     { 
      existingCategories.Add(categoriesReader["Title"].ToString()); 
     } 
    } 
} 

if (!existingCategories.Contains(newCategory)) 
{ 
    SqlCommand addCategory = new SqlCommand("insert into Movie.Category (SourceId, Title) values (@sourceId, @title)", sqlConnection, sqlTransaction); 

    // Now try to make a mistake and write/copy-paste getCategories instead of addCategory. It will not compile. 
    addCategory.Parameters.AddWithValue("@sourceId", sourceId); 
    addCategory.Parameters.AddWithValue("@title", newCategory); 
    addCategory.ExecuteNonQuery(); 
} 

Jetzt zeigt StyleCop jedes Mal eine Warnung an, wenn ein Block einer leeren Zeile folgt. Wenn Sie jedoch keine Leerzeile einfügen, wird der Code viel schwieriger zu verstehen sein.

// Something like: 
Collection<string> existingCategories = new Collection<string>(); 
{ 
    // Code here 
} 

// can be understood as (is it easy to notice that semicolon is missing?): 
Collection<string> existingCategories = new Collection<string>() 
{ 
    // Code here 
} 

So

  1. Gibt es etwas falsch Klammern Sie sich mit der Code-Blöcke zu erstellen, für variable Umfang Zwecke?

  2. Wenn alles in Ordnung ist, wie kann man es lesbarer machen, ohne die Regeln des StyleCop zu verletzen?

+3

Diese werden anonyme Blöcke genannt. Related: http://stackoverflow.com/questions/85282/what-is-the-value-of-an-anonymous-unattached-block-in-c und http://stackoverflow.com/questions/500006/what- is-the-intention-of-anonyme-blocks-in-c-style-languages ​​ –

Antwort

5

Ich glaube nicht, dass es etwas falsch daran ist, Klammern nur zur Begrenzung des Umfangs zu verwenden - es kann manchmal sehr nützlich sein.

Fall in Punkt - Ich stieß einmal auf eine Profiling-Bibliothek, die Profile Objekte zu Zeitabschnitten des Codes verwendet. Diese arbeiteten, indem sie die Zeit von ihrer Entstehung bis zur Zerstörung maßen und deshalb am besten funktionierten, indem sie auf dem Stapel erstellt und dann zerstört wurden, wenn sie außer Reichweite gerieten, und so die in diesem bestimmten Bereich verbrachte Zeit messen konnten. Wenn Sie etwas zeitlich festlegen wollten, das nicht von Natur aus einen eigenen Gültigkeitsbereich hatte, dann war das Hinzufügen zusätzlicher Klammern zur Definition dieses Bereichs wahrscheinlich der beste Weg.

Für die Lesbarkeit kann ich verstehen, warum StyleCop es nicht mag, aber jeder mit Erfahrung in C/C++/Java/C#/... weiß, dass ein geschweifte Paar einen Bereich definiert, und es sollte fair sein offensichtlich, dass das ist, was du versuchst zu tun.

12

Verwenden Sie die using Anweisung anstelle von bloßen Klammer blockiert.

Dies wird die Warnungen vermeiden und Ihren Code auch in Bezug auf Ressourcen effizienter machen.

Aus einer größeren Perspektive sollten Sie diese Methode in kleinere Methoden aufteilen. Die Verwendung einer weiteren SqlCommand gefolgt von einer anderen wird normalerweise besser ausgeführt, indem eine Methode aufgerufen wird, gefolgt von einer anderen. Jede Methode würde dann ihre eigene lokale SqlCommand verwenden.

+8

Ich glaube, using() benötigt eine IDisposable, die er in diesem Zusammenhang möglicherweise nicht haben. –

+0

Dies gilt in diesem speziellen Szenario (da 'SqlCommand'' IDisposable' implementiert, aber seinen allgemeinen Fall nicht lösen würde. –

+0

Es ist hässlich, aber du kannst 'do {...} while (false);' stattdessen verwenden "Das Ausschalten der Warnung wäre jedoch wahrscheinlich eine bessere Lösung. –

18

Es gibt nichts falsch per se mit Sperrcode, aber Sie müssen überlegen, warum Sie es tun.

Wenn Sie Code kopieren und einfügen, befinden Sie sich wahrscheinlich in einer Situation, in der Sie den Code refactorieren und wiederholt aufgerufene Funktionen erstellen sollten, anstatt ähnliche, aber unterschiedliche Code-Blöcke wiederholt auszuführen.

+4

Ich stimme zu, es gibt nichts technisch falsches. Es ist eine stilistische Beschwerde und möglicherweise ein Warnzeichen für lange Funktionen, die wirklich in kleinere und überschaubarere Teile aufgeteilt werden sollten. –

+0

"Sie befinden sich wahrscheinlich in einer Situation, in der Sie den Code neu gestalten sollten": Es geht nicht um das Kopieren/Einfügen großer Codeblöcke. Das gleiche Problem tritt auf, wenn Intellisense verwendet wird, wenn zwei Variablen ähnliche Namen haben ('sqlGetProductFromTable' vs.' sqlAddProductToTable'). Es ist leicht, den Variablennamen falsch zu schreiben, und da der Code für den Compiler vollkommen korrekt ist, wird er ausgeführt, erzeugt aber etwas Unerwartetes. –

+0

@MainMa: Die Wiederverwendung der Blöcke ist nicht der einzige Grund zum Refactoring. Eine Methode, die einfach riesig ist, kann ein guter Grund sein, sie in kleinere Teile aufzuteilen. –

4

Ich denke solche Blöcke ist eine gute Idee, ich benutze ihre oft. Es ist nützlich, wenn Sie Blöcke des Codes trennen müssen, die zu klein sind, um in die Methode extrahiert zu werden, oder wenn die Methode aus wenigen Codeblöcken besteht sieht wie einander aus, aber nicht mit der gleichen Logik. Es erlaubt Variablen denselben Namen zu geben, ohne Konflikte zu benennen, und dies macht den Methodenkörper lesbarer.

Übrigens, meine Meinung StyleCop hat Standardregelsatz mit mehr Regeln, deren Zweckmäßigkeit strittig ist.

3

Ich würde sagen, wenn ich an diesem Code nach Ihnen arbeiten würde, wäre ich ein wenig offput durch Ihre Verwendung von Umfang. Es ist nicht, afaik, gängige Praxis.

Ich würde es als einen Geruch betrachten, dass Sie das tun würden. Ich denke, die bessere Praxis wäre es, jeden Bereich mit vollständig beschreibenden Namen und Dokumentationen in eine eigene Methode zu zerlegen.

0

Wenn Sie Klammern verwenden müssen, um den Umfang Ihrer Variablen zu begrenzen, sind Ihre Methoden wahrscheinlich schon zu lang. Ich wollte nur betonen, was die anderen schon geschrieben haben.

Verwandte Themen