StyleCop – Manchmal muss man auch Regeln brechen – Rule Suppressions

Jemand, der wie ich, StyleCop zur Einhaltung und Durchsetzung von Coding Styles einsetzt, versucht im allgemeinen möglichst viele der vorgegebenen Regeln aktiviert zu lassen und beim schreiben von Source Code diese Regeln um und einzusetzen um einheitlichen Source Code zu produzieren.

Je nach Einsatzgebiet, globalen Vorgaben oder Absprachen der Entwicklerteams kann es natürlich vorkommen, dass einzelne Regeln generell deaktiviert werden.Dies sollte dann aber wirklich gut überlegt sein, und auch nicht ständig geändert werden und sozusagen zum eigenen Regelwerk werden.

Nun kann es aber trotz dem größten Willen alle aktiven Regeln einzuhalten, an der einen oder anderen Stelle dazu kommen , dass man Code schreibt, der in diesem speziellen Fall genau so gewünscht ist,  aber so wie er geschrieben wurde gegen eine Regel verstößt.

Wenn man ein Tool wie StyleCop einsetzt, dann ist dass Ziel das ein Projekt ohne StyleCop Warnungen durchläuft. Also ohne einen Bruch der Regeln. Wenn aber an einer bestimmten Stelle bewusst eine Regel gebrochen wird, dann sollte dies Möglich sein, sollte aber genau dokumentiert sein.

Um diesem Umstand gerecht zu werden, gibt es die Möglichkeit bestimmte Regeln auf verschiedenen Ebenen zu unterdrücken.

Mit Ebenen sind hier jede Art von Code Elementen gemeint wie:

  • Klassen
  • Methoden
  • Felder
  • Eigenschaften
  • usw.

Doch zuerst möchte ich mal ein solches Beispiel zeigen, bei dem StyleCop eine Warnmeldung ausgibt, ich aber den Code aus genau so und nicht anders schreiben möchte. Wir müssen an dieser Stelle nicht über den Code diskutieren, da er hier lediglich als Beispiel dienen soll.

Hier nun die gewollte Code Variante, die aber von StyleCop angemeckert wird:

string cmd = new StringBuilder("PORT ").
  Append((short)hostBytes[0]).Append(",").
  Append((short)hostBytes[1]).Append(",").
  Append((short)hostBytes[2]).Append(",").
  Append((short)hostBytes[3]).Append(",").
  Append((short)portBytes[0]).Append(",").
  Append((short)portBytes[1]).ToString();
 

StyleCop gibt bei diesem Code die nachfolgenden Meldungen aus:

StyleCop kommt hier nicht mit der Aufteilung der Methodenaufrufe auf mehrere Zeilen klar.

Ich möchte aber auf keinen Fall den folgenden Code in meinem Source Code haben, der würde zwar den Ansprüchen von StyleCop entsprechen aber nicht meinen.

string cmd = new StringBuilder("PORT ").Append((short)hostBytes[0]).Append(",").Append((short)hostBytes[1]).Append(",").Append((short)hostBytes[2]).Append(",").Append((short)hostBytes[3]).Append(",").Append((short)portBytes[0]).Append(",").Append((short)portBytes[1]).ToString();

Alternativ würde StyleCop auch mit dem nachfolgenden Code zufrieden sein. Doch den möchte ich auch nicht.

StringBuilder stringBuilder = new StringBuilder("PORT ");
stringBuilder.Append((short)hostBytes[0]);
stringBuilder.Append(",");
stringBuilder.Append((short)hostBytes[1]);
stringBuilder.Append(",");
stringBuilder.Append((short)hostBytes[2]);
stringBuilder.Append(",");
stringBuilder.Append((short)hostBytes[3]);
stringBuilder.Append(",");
stringBuilder.Append((short)portBytes[0]);
stringBuilder.Append(",");
stringBuilder.Append((short)portBytes[1]);
stringBuilder.ToString();
string cmd = stringBuilder.ToString();

Wenn ich also dich den Code verwenden möchte den StyleCop angemeckert ohne das dadurch der Code angemeckert wird, muss ich StyleCop dazu bringen genau an dieser Stelle die Meldungen zu unterdrücken.

Hierzu verwenden wird aus dem NameSpace System.Diagnostics.CodeAnalysis ein Attribut mit dem Namen SuppressMessage und packen dieses Attribut an die Methode, Klasse oder was auch immer, um die StyleCop Regel genau an der gewünschten Stelle zu unterdrücken.

Nähere Informationen zur Verwendung der „Rule Suppression“ für StyleCop findet man hier auf der Codeplex Seite von StyleCop

Nun aber das Beispiel anhand einer Methode um die StyleCop Meldungen für diese Methode zu untedrücken.

[SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1019:MemberAccessSymbolsMustBeSpacedCorrectly")]
internal static string TestRule(byte[] hostBytes)
{
    string cmd = new StringBuilder("PORT ").
        Append((short)hostBytes[0]).Append(",").
        Append((short)hostBytes[1]).Append(",").
        Append((short)hostBytes[2]).Append(",").
        Append((short)hostBytes[3]).Append(",").ToString();

    return cmd;
}

Wobei fogendes gilt:

Für die StyleCop Regeln kommen folgende Kategorien in betracht:

  • StyleCop.CSharp.DocumentationRules
  • StyleCop.CSharp.LayoutRules
  • StyleCop.CSharp.MaintainabilityRules
  • StyleCop.CSharp.NamingRules
  • StyleCop.CSharp.OrderingRules
  • StyleCop.CSharp.ReadabilityRules
  • StyleCop.CSharp.SpacingRules

Als Rule ID muss die jeweilige Rule ID bestehend aus der Nummer und dem Text ab besten aus dem Rules Konfigurations Bereich des SyteleCop Add In herause gelesen werden. (Siehe nachfolgende Abbildung)

7 Gedanken zu „StyleCop – Manchmal muss man auch Regeln brechen – Rule Suppressions“

  1. Hallo HP,

    würdest du statt:
    string cmd = new StringBuilder(„PORT „).
    Append((short)hostBytes[0]).Append(„,“).
    Append((short)hostBytes[1]).Append(„,“).

    den Punkt auf die jeweils neue Zeile:
    string cmd = new StringBuilder(„PORT „)
    .Append((short)hostBytes[0]).Append(„,“)
    .Append((short)hostBytes[1]).Append(„,“)

    sollte AFAIK der StyleCop eigentlich die Schnauze halten.

    Servus,
    Klaus

    1. Hallo Klaus,
      du hast natürlich Recht, damit wäre die Meldung an dieser Stelle zu umgehen, wie auch mit den anderen beiden Varianten die ich aufgezeigt habe.

      Ich habe das aber nur als Beispiel verwendet um zu zeigen wie man bestimmte StyleCop Regeln unterdrücken kann.

      Beste Grüße
      HP

      1. Ahh, OK.
        Jetzt hab ich’s gefressen 🙂

        du hättest dann aber gleich noch den Parameter Justification erklären können, damit für andere auch klar ist warum diese oder andere Regeln ausgenommen wurden.

        Servus,
        Klaus

  2. Hat funktioniert, allerdings erst nachdem ich die Category mit „Microsoft.“ vorangestellt benutze: [SuppressMessage(„Microsoft.StyleCop.CSharp.OrderingRules“

    Hast Du eine Ahnung warum das so ist?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.