2009-07-28 12 views
52

Perché ottengo l'avviso del compilatorePerché questo nome con un trattino basso non è conforme a CLS?

non Identifier 'Logic.DomainObjectBase._isNew' è compatibile con CLS

per il seguente codice?

public abstract class DomainObjectBase 
{ 
    protected bool _isNew; 
} 
+23

probabilmente non dovrebbe essere marcatura membri non-private con un carattere di sottolineatura comunque. So che ognuno ha il proprio stile, ma altri quasi certamente pensano che il campo sia privato fuori dalle convenzioni. –

+0

@ Eds. Quale convenzione? – Pharap

+0

Sembra essere stata una convenzione VB in una volta, sembra anche fuori moda per C++, C#, più dettagli di quelli che si adatteranno a questa casella trovata qui: https://stackoverflow.com/questions/3136594/naming- convention-underscore-in-cc-variables – MatthewMartin

risposta

77

Dal Common Language Specification:

CLS-compliant compilatori di linguaggio devono seguire le regole di cui all'allegato 7 del Technical Report 15 della standard Unicode 3.0, che regola il set di caratteri che possono iniziare ed essere inclusi in identificatori . Questo standard è disponibile dal sito Web del Consorzio Unicode.

Se look this up:

Cioè, il primo carattere di un identificatore può essere una lettera maiuscola, minuscola, lettera Titlecase, lettera modificatore, altra lettera o numero di lettera. I caratteri successivi di un identificatore possono essere uno qualsiasi di questi, oltre a segni di non spaziatura, segni di spaziatura combinati, numeri decimali, punteggiature del connettore e codici di formattazione (come il segno con il simbolo di destra e di sinistra). Normalmente i codici di formattazione devono essere filtrati prima di memorizzare o confrontare gli identificatori.

Fondamentalmente, non è possibile avviare un identificatore con un carattere di sottolineatura - questo viola CLS conforme su un campo visibile (pubblico/protetto).

+0

http://msdn.microsoft.com/en-us/library/k5645wwb(v=VS.100).aspx – JohnB

+1

Che cos'è un "numero di lettera"? – Kevin

+2

@Kevin: tutti i termini nel frammento sopra si riferiscono alle categorie Unicode: "Lettera, maiuscolo", "Lettera, lettere minuscole", "Lettera, Titlecase", "Lettera, modificatore", "Lettera, altro" e "Numero, lettera". I numeri romani sono un esempio di un 'numero di lettere'. Vedi http://www.fileformat.info/info/unicode/category/Nl/list.htm – Joren

28

Il principale underscore concomitante con _isNew essendo visibile (cioè, non private).

+12

+1 Ma è necessario includere il fatto che il membro sia * non-privato * che, insieme al trattino basso principale, rende il nome del membro non conforme a CLS. –

1

È il trattino basso. Vedi questo article.

0

Poiché il nome del membro dati, _isNew, inizia con un trattino basso.

2

Un identificatore conforme a CLS non deve iniziare con un trattino di sottolineatura.

7

Il trattino basso causa il problema. La pratica comune è che il carattere di sottolineatura è riservato ai campi privati. i membri protetti/pubblici dovrebbero essere correttamente assegnati e nominati.

Ad esempio:

public abstract class DomainObjectBase{ 
    private bool _isNew; 
    protected bool IsNew { get { return _isNew; } set { _isNew = value;} } 
} 

O, se si desidera utilizzare 3.x e sbarazzarsi del campo privato:

public abstract class DomainObjectBase{ 
    protected bool IsNew { get; set; } 
} 
+0

Grazie! Lo segnerei come la seconda migliore risposta se potessi. – MatthewMartin

1

Il leader _ è non compatibile con CLS

Microsoft StyleCop analizzerà il codice e fornirà collegamenti ai documenti pertinenti che spiegano il motivo per cui non è conforme a CLS.

+1

Mi piace l'idea di StyleCop, ma le sue regole sono in conflitto con le regole FxCop, il riformattore di Resharper e il riformattatore di Visual Studio. – MatthewMartin

+0

StyleCop e FxCop sono entrambi prodotti da Microsoft (anche se da diversi team di prodotto), tuttavia credo che StyleCop sia il più recente, e quindi più preferito se si desidera utilizzare uno stile di codice "Microsoft". – Frozenskys

38

CLS compliance ha a che fare con l'interoperabilità tra le diverse lingue .NET. La proprietà non è conforme a CLS, poiché inizia con un carattere di sottolineatura ed è pubblica (nota: le proprietà protette in una classe pubblica sono accessibili dall'esterno dell'assieme).Anche se questo funzionerà se si accede alla proprietà da C#, potrebbe non essere accessibile se si accede da altri linguaggi .NET che non consentono i caratteri di sottolineatura all'inizio dei nomi di proprietà, quindi non è conforme a CLS.

hai trovato questo errore del compilatore, perché da qualche parte nel codice che avete etichettato l'assembly come compatibile con CLS con una linea simile a questa:

[assembly: CLSCompliant(true)] 

Visual Studio include questa riga nel file AssemblyInfo.cs che può essere trovato sotto Proprietà nella maggior parte dei progetti.

Per ovviare a questo errore è possibile:

  1. Rinominare la vostra proprietà (consigliato):

    protected bool isNew; 
    
  2. Impostare tutta la vostra assemblea per essere non compatibile con CLS:

    [assembly: CLSCompliant(false)] 
    
  3. Aggiungi un attributo solo al tuo immobile:

    [CLSCompliant(false)] 
    protected bool _isNew; 
    
  4. Modificare l'ambito della proprietà, in modo che non possa essere visualizzato all'esterno dell'assieme.

    private bool _isNew; 
    
+0

Quindi, quando si dispone di una proprietà pubblica con una variabile protetta, qual è la migliore convenzione? –

+3

Personalmente mi piace rendere tutti i campi privati. Se ho bisogno di aumentare lo scope, lo avvolgerei in un Property Get/Set. –

+0

@MartinBrown: ci sono molte situazioni in cui una classe avrà una proprietà pubblica il cui setter chiama un metodo protetto che elabora gli aggiornamenti, ma dove i tipi derivati ​​potrebbero avere una legittima necessità di usare direttamente il campo e postare aggiornamenti successivamente (ad esempio se una classe deriva da un controllo ha un metodo per modificare sia il suo colore che la didascalia, ma la base no, potrebbe essere utile per la classe derivata modificare entrambi i campi e quindi chiamare il metodo di aggiornamento una volta). La mia inclinazione sarebbe quella di usare "Caratteristico" e "_caratteristico", dal momento che sia VB.NET che C# lo accettano. Che cosa suggeriresti? – supercat