2013-05-04 8 views
7

In C# möchte ich "intelligente" Enums machen, ähnlich wie es in Java möglich ist, wo es mehr Informationen gibt, die an einen Enum-Wert angehängt sind als nur das darunterliegende int. Ich war gerade auf einem Schema, eine Klasse zu machen (statt eines ENUM), wie in der folgenden einfachen Beispiel:C# -Mutabilität - VS-Code-Analyse gibt mir CA2104? Scheint ... arm. Missverständnis ich?

public sealed class C 
{ 
    public static readonly C C1 = new C(0, 1); 
    public static readonly C C2 = new C(2, 3); 

    private readonly int x; 
    private readonly int y; 

    private C(int x, int y) 
    { 
     this.x = x; 
     this.y = y; 
    } 

    public int X 
    { 
     get 
     { 
      return this.x; 
     } 
    } 

    public int Y 
    { 
     get 
     { 
      return this.y; 
     } 
    } 
} 

Aber wenn ich Visual Studio „Code Analyzer“ auf das laufen, es gibt mir C2104 Warnung " Deklarierbare schreibgeschützte Referenztypen nicht deklarieren ".

Ich bekomme, warum Sie im Allgemeinen nicht möchten, read-only veränderbare Referenztypen zu deklarieren, aber ... meine Klasse ist nicht änderbar, oder?

Wenn Sie die Dokumente für die Warnung lesen, scheint es, als würden sie nur davon ausgehen, dass jeder schreibgeschützte Referenztyp änderbar ist. Zum Beispiel sagt es, dass, wenn der Typ wirklich unveränderlich ist, dann zögern Sie diese Warnung zu unterdrücken. Und in der Tat gibt es mir die gleiche Warnung für die folgende noch einfachere Klasse:

public sealed class C 
{ 
    public static readonly C C1 = new C(); 
    public static readonly C C2 = new C(); 

    private C() 
    { 
    } 
} 

So, OK, es sei denn, ich ernsthaft Veränderlichkeit Mißverständnis bin, ist CA2104 nicht verstehen. Und es ist meine Empfehlung, die Warnung für jede Zeile, in der sie auftaucht, zu unterdrücken, solange ich sicher bin, dass die Klasse wirklich unveränderlich ist. Aber:

(1) Also, wenn ich diese Prüfung vollständig abwende, muss ich es jedes Mal unterdrücken, wenn ich jemals ein unveränderliches Nur-Lese-Mitglied verwende, das ich HUNDERTE von Zeiten für eine gegebene Aufzählung tun könnte?

(2) Aber schlimmer, auch wenn ich das tue, dann kann jemand später versehentlich die Veränderlichkeit einführen, aber jemand anderes wird immer noch das falsche Gefühl der Sicherheit haben, dass jemand die Unterdrückung dort mit der Aussage "Ich habe überprüft und das ist unveränderlich "?

+0

Ich hatte eine ähnliche Frage: http://stackoverflow.com/questions/15740025/the-ca2104-warning-is-there-any-way-to-mark-a-class-as-immutable- zu unterdrücken –

Antwort

5

Sie haben Recht - das ist ein falscher positiver in diesem Szenario. Sie haben nur die Wahl, die Warnung einzeln zu unterdrücken oder zu deaktivieren, und die Nachteile sind genau so, wie Sie es für jede Option beschrieben haben.

Weitere Möglichkeiten, diese Warnung zu vermeiden sind:

  • nicht statische Felder anwenden. Stattdessen können Sie eine statische Eigenschaft mit einem öffentlichen get und einem privaten Satz verwenden und im Konstruktor statt inline initialisieren.

  • Machen Sie diese unveränderlichen Werttypen, die die Warnung umgehen, aber in einigen Szenarien möglicherweise ein anderes Verhalten zeigen. Dies kann in Ihrem Fall eine Option sein oder nicht.

+0

Das Ändern in einen Werttyp hat funktioniert - danke! Ich denke, es sollte in Ordnung sein, wie ich es benutzen möchte, also werde ich damit anfangen und alle anderen Probleme lösen, die auftreten können, wenn ich auf sie stoße. Danke noch einmal! – user2350774

+0

@ user2350774 Die Verwendung von Eigenschaften ist eigentlich meine Präferenz. Öffentliche Felder haben viele Nachteile (Sie können hier nach Unmengen von Gründen suchen, um Felder in der öffentlichen API zu vermeiden) –

+0

Nicht sicher, dass ich das verstehe - Ich habe Eigenschaften für X und Y verwendet. Oder schlagen Sie vor, dass ich auch Eigenschaften verwenden soll für die statischen Dinge, die ich im Wesentlichen als enum-Werte behandeln möchte? – user2350774