2010-12-27 14 views
23

In primo luogo, so che questa domanda è stato chiesto diverse volte prima e che, alla fine, è in gran parte una questione di preferenze personali, ma leggendo tutti i thread sull'argomento, alcune cose non sono chiare a me.Convenzione di denominazione delle campi privati ​​

In sostanza, qualcosa che la maggior parte delle persone sono d'accordo con almeno è che gli pubblica dovrebbe essere PascalCased mentre i membri privati ​​dovrebbero essere lowerCamelCased.

La materia che di solito porta il dibattito è se non prefisso membri privati ​​da un trattino, o qualsiasi altra cosa. Anteponendo viola diverse regole StyleCop (che può ovviamente essere spento però)

Il razionale di non anteponendo è che si dovrebbe utilizzare questo. prefisso invece.

Il problema che ho è che non capisco come si sta facendo la differenza? Voglio dire, non è che non puoi usare questo su un membro pubblico comunque all'interno di una classe.

Immaginiamo una classe Customer, cercando in questo modo:

class Customer 
{ 
    private int age; 

    public int Age 
    { 
     get { return this.age; } 
     set { this.age = value; } 
    } 
} 

(Ovviamente, in un caso come semplice, ho potuto utilizzare un autoproperty, ma questo è solo un esempio).

Se ho aggiunto una seconda proprietà all'interno di questa classe, nulla impedirebbe mi riferisco ad esso utilizzando this.Age (la proprietà pubblica) piuttosto che this.age (settore privato). A volte, potrebbe anche essere lavabile, se qualche validazione o formattazione è stata applicata a livello getter.

Inoltre, se alcune altre proprietà della mia classe dovessero modificare l'età del cliente, avrebbe senso utilizzare la proprietà piuttosto che il campo di supporto direttamente poiché il setter potrebbe anche implementare alcune convalide di regole aziendali, giusto?

In altre parole, non vedo davvero come questa parola chiave eviti la confusione tra membri di backing privati ​​e proprietà pubbliche in quanto può essere utilizzata su entrambi e IntelliSense mostra entrambi?

Grazie.

risposta

13

Hai perfettamente ragione. Non è così.

L'utilizzo di this è un modo per garantire che si stia utilizzando il membro della classe, in caso di conflitti di denominazione (ad esempio un nome di parametro identico al nome di un campo).

Per me, i membri pubblici del rivestimento pasquale e i membri privati ​​del rivestimento del cammello sono sempre stati un convegno abbastanza per funzionare bene.

8

Utilizzando this.age potrebbe aiutare a distinguere tra l'archivio di backup della vostra proprietà Age e un parametro age di un metodo sull'oggetto:

public bool CheckIfOlderThan(int age) 
{ 
    // in here, just using "age" isn't clear - is it the method parameter? 
    // The internal field?? Using this.age make that clear! 
    return (this.age >= age); 
} 

Naturalmente, in questo caso, si potrebbe anche dare il vostro parametro a meno nome confuso per evitare qualsiasi scontro ....

Ma nella definizione effettiva della proprietà - la lettura e la memorizzazione del suo valore nel backing store - l'aggiunta di this. non aggiunge nulla. Alcune persone che conosco preferiscono usare sempre il prefisso this. - non solo quando è necessario - preferenze personali, in realtà ...

7

La prefissazione dei campi privati ​​con trattino basso è praticamente la stessa cosa che usare "questo". Tuttavia, sottolineatura è più veloce da usare, più breve e più elegante per me (questo viene da Java credo).

Avere lo stesso nome per i parametri di funzione e per i campi privati ​​mi sembra un po 'complicato. Non solo una volta ho dimenticato di usare "questo" che ha portato a NullPointerException (sì, ho fatto java un giorno ... :)).

Per quanto ne so, non viola alcuna regola FxCop, in quanto non è una notazione ungherese.

+2

E 'sicuramente non viene da Java. In C/C++ gli identificatori che iniziano con underscore sono solitamente riservati per il compilatore. –

43

preferisco fortemente la convenzione leader "_" per i campi privati, anche se non segue le convenzioni MS:

  1. Esso elimina i conflitti con i nomi dei parametri cammello con carter - non c'è bisogno di usare "questo"

  2. È un indicatore visivo che sta leggendo lo stato interno persistente dell'oggetto o, cosa più importante, viene scritto. È una bandiera che dice "" questo ha effetti collaterali al di fuori del particolare metodo che mi capita di vedere ", che è molto importante sapere quando si guarda il codice non familiare.

+11

Sto cercando di capire i pro del carattere di sottolineatura, ma posso semplicemente dire: Usa "questo".: 1. Elimina la necessità di "_". 2. È un indicatore visivo che indica lo stato persistente interno dell'oggetto ... Vedi il mio punto. La tua argomentazione funziona in entrambi i modi. – Noich

+8

Lo fa davvero. Un paio di motivi per cui preferisco _ su "questo" - è più compatto, e non è opzionale - il programma non verrà compilato se si dimentica il _ in una variabile di riferimento. Ma penso che sia principalmente una preferenza personale ... –

+1

Annuncio 2: Non è questo che dovrebbe fare l'evidenziazione della sintassi? – Jirka

-5

suggerisco questa convenzione:

class Customer{ 
    private int Age_; 
    public int Age{ 
     get{return Age_;} 
     set{Age_ = value;} 
    } 
    public void MultiplyAge(int age){ 
     Age_ *= age; 
    } 
} 

Gli altri suggerimenti sono sicuramente vale la pena considerare come bene e le linee guida .Net che ho letto non sono rigorosi nel loro suggerimenti sulla denominazione membri privati, ma un finale di sottolineatura non è una cattiva scelta per i seguenti motivi:

  • una sottolineatura finale (ad es Glaciale_) è comunemente usato in C++ per i campi privati, perché una sottolineatura di partenza (ad es _Age) potrebbe entrare in conflitto w con il compilatore. Vedi this post per maggiori informazioni. Ciò non ha importanza per C#, naturalmente, ma potrebbe essere bello mettere in relazione le convenzioni tra le lingue.
  • caso cammello inferiore (ad esempio età) viene spesso utilizzato in .Net per rappresentare variabili locali e parametri del metodo.
  • La differenziazione basata solo sul caso (ad esempio età vs età) riduce la portabilità facile avanti e indietro tra le lingue che non si preoccupano del caso (come VB.Net, a seconda delle opzioni di configurazione).

Ecco un esempio di come ho comunemente finire in uno scenario in cui questa convenzione è stata utile per me:

class Customer{ 
    private int? Age_; 
    public int Age{get{ 
    if(Age_ == null){ 
     // Really computationally expensive operation for retrieving and setting 
     // Age_ based on results from some external system goes here... or 
     // something like that. 
    } 
    return (int)Age_; 
    }} 
} 
+1

Ho notato che ho ricevuto molto dolore per questa risposta. È giusto, sicuramente, ma puoi dirmi quali sono i tuoi problemi con la mia sottomissione? Non sono critico Sono solo curioso. – scradam

+4

Direi che è perché mettere un trattino basso alla fine di un identificatore non è comune (penso che non sia comune perché è la prima volta che lo vedo, anche se devo ammettere che non ho visto molto codice.). –

Problemi correlati