2013-05-04 15 views
7

In C#, voglio rendere "intelligenti" le enumerazioni, un po 'come è possibile in Java, dove ci sono più informazioni collegate a un valore enum che solo l'int sottostante. Mi è capitato su uno schema di fare una classe (invece di un enum), come nel seguente esempio semplice:C# mutabilità - Analisi del codice VS mi dà CA2104? Sembra ... povero. Sto fraintendendo?

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; 
     } 
    } 
} 

Ma quando corro "Code Analyzer" di Visual Studio su questo, mi dà avviso C2104, " Non dichiarare solo i tipi di riferimento modificabili ".

Capisco perché generalmente non si desidera dichiarare solo tipi di riferimento mutabili, ma ... la mia classe non è mutabile, vero?

Leggendo i documenti per l'avviso, sembra che si stia semplicemente ipotizzando che qualsiasi tipo di riferimento di sola lettura sia modificabile. Ad esempio, dice che se il tipo è davvero immutabile, allora sentiti libero di sopprimere questo avviso. E infatti mi dà lo stesso avvertimento per la seguente classe ancora più semplice:

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

    private C() 
    { 
    } 
} 

Quindi, OK, a meno che non sto seriamente equivoco mutevolezza, CA2104 non la comprende. E la sua raccomandazione è per me di sopprimere l'avvertimento per ogni riga in cui viene fuori, finché sono sicuro che la classe è davvero immutabile. Ma:

(1) Quindi, a meno che non spegni completamente questo controllo, devo sopprimerlo ogni volta che uso un membro immutabile di sola lettura, che potrei fare CENTO di volte per ogni enumerazione data?

(2) Ma peggio, anche se lo faccio, allora qualcuno può inavvertitamente introdurre la mutabilità, ma qualcun altro avrà ancora il falso senso di sicurezza dato dal fatto che qualcuno ha messo manualmente la soppressione dicendo "Ho controllato e questo è immutabile "?

+0

avevo una domanda simile: http://stackoverflow.com/questions/15740025/the-ca2104-warning-is-there-any-way-to-mark-a-class-as-immutable- to-sopprimere –

risposta

5

Si è corretto - questo è un falso positivo in questo scenario. Le tue uniche scelte sono di sopprimere individualmente o disattivare l'avviso, e gli svantaggi sono esattamente come hai descritto per ciascuna opzione.

Altre opzioni per evitare questo avvertimento includono:

  • Non utilizzare campi statici. Invece, è possibile utilizzare una proprietà statica con un set pubblico privato e privato e inizializzarsi nel costruttore anziché inline.

  • Crea questi tipi di valore immutabili, che ignorano l'avviso, ma potenzialmente danno un comportamento diverso in alcuni scenari. Questo potrebbe o non potrebbe essere un'opzione nel tuo caso.

+0

Cambiarlo in un tipo di valore ha funzionato - grazie! Penso che dovrebbe essere OK per come voglio usarlo, quindi inizierò a farlo in quel modo e ad affrontare qualsiasi altro problema che potrebbe sorgere quando li incontro. Grazie ancora! – user2350774

+0

@ user2350774 L'utilizzo delle proprietà è in realtà la mia preferenza. I campi pubblici hanno molti svantaggi (puoi cercare qui per un sacco di motivi per evitare campi nell'API pubblica) –

+0

Non sono sicuro di averlo capito - Ho usato le proprietà per X e Y. O stai suggerendo che dovrei usare anche le proprietà per le cose statiche che voglio trattare, essenzialmente, come valori enum? – user2350774