Proprietà vs Metodi

Domanda veloce: quando decidi di utilizzare le proprietà (in C #) e quando decidi di utilizzare i metodi?

Siamo impegnati in questo dibattito e abbiamo trovato alcune aree in cui è discutibile se dovremmo usare una proprietà o un metodo. Un esempio è questo:

public void SetLabel(string text) { Label.Text = text; } 

Nell’esempio, Label è un controllo su una pagina ASPX. Esiste un principio che può governare la decisione (in questo caso) se rendere questo un metodo o una proprietà.

Accetterò la risposta che è la più generale e completa, ma che tocca anche l’esempio che ho dato.

Dalla sezione Scelta tra proprietà e metodi delle Linee guida di progettazione per lo sviluppo di librerie di classi:

In generale, i metodi rappresentano azioni e le proprietà rappresentano i dati. Le proprietà sono pensate per essere utilizzate come campi, il che significa che le proprietà non devono essere computazionalmente complesse o produrre effetti collaterali. Quando non viola le seguenti linee guida, considera l’utilizzo di una proprietà, piuttosto che un metodo, perché gli sviluppatori meno esperti trovano le proprietà più facili da usare.

Sì, se tutto quello che stai facendo è ottenere e impostare, usa una proprietà.

Se stai facendo qualcosa di complesso che può interessare diversi membri di dati, un metodo è più appropriato. O se il tuo get assume parametri o il tuo setter prende più di un parametro di valore.

Al centro c’è un’area grigia dove la linea può essere un po ‘sfocata. Non esiste una regola dura e veloce e diverse persone a volte non sono d’accordo sul fatto che qualcosa dovrebbe essere una proprietà o un metodo. L’importante è essere (relativamente) coerenti con come lo fai (o come lo fa il tuo team).

Sono in gran parte intercambiabili ma una proprietà segnala all’utente che l’implementazione è relativamente “semplice”. Oh e la syntax è un po ‘più pulita.

In generale, la mia filosofia è che se inizi a scrivere un nome di metodo che inizia con get o set e prende zero o un parametro (rispettivamente), allora è un candidato principale per una proprietà.

Se stai impostando una proprietà reale del tuo object, allora usi una proprietà.

Se si sta eseguendo un’attività / funzionalità, si utilizza un metodo.

Nel tuo esempio, è impostata una proprietà definita.

Se la tua funzionalità fosse, invece, AppendToLabel, dovresti utilizzare un metodo.

Le proprietà sono un modo per iniettare o recuperare dati da un object. Creano un’astrazione su variabili o dati all’interno di una class. Sono analoghi ai getter e setter in Java.

I metodi incapsulano un’operazione.

In generale, utilizzo le proprietà per esporre singoli bit di dati o piccoli calcoli su una class, come l’imposta sulle vendite. Che deriva dal numero di articoli e dal loro costo in un carrello.

Uso i metodi quando creo un’operazione, come il recupero dei dati dal database. Qualsiasi operazione che abbia parti in movimento, è un candidato per un metodo.

Nel tuo esempio di codice lo racchiuderei in una proprietà se ho bisogno di accedervi al di fuori della sua class contenente:

 public Label Title { get{ return titleLabel;} set{ titleLabel = value;} } 

Impostazione del testo:

 Title.Text = "Properties vs Methods"; 

Se stavo solo impostando la proprietà Text dell’etichetta questo è come lo farei:

 public string Title { get{ return titleLabel.Text;} set{ titleLabel.Text = value;} } 

Impostazione del testo:

 Title = "Properties vs Methods"; 

Basta guardare solo il nome … “Proprietà”. Cosa significa? Il dizionario lo definisce in molti modi, ma in questo caso “un attributo essenziale o distintivo o la qualità di una cosa” si adatta meglio.

Pensa allo scopo dell’azione. Stai, infatti, alterando o recuperando “un attributo essenziale o distintivo”? Nel tuo esempio, stai utilizzando una funzione per impostare una proprietà di una casella di testo. Sembra un po ‘sciocco, vero?

Le proprietà sono davvero funzioni. Compilano tutti fino a getXXX () e setXXX (). Li nasconde semplicemente nello zucchero sintattico, ma è lo zucchero che fornisce un significato semantico al processo.

Pensa a proprietà come attributi. Una macchina ha molte caratteristiche. Colore, MPG, Modello, ecc. Non tutte le proprietà sono impostabili, alcune sono calcolabili.

Nel frattempo, un metodo è un’azione. GetColor dovrebbe essere una proprietà. GetFile () dovrebbe essere una funzione. Un’altra regola empirica è che, se non cambia lo stato dell’object, dovrebbe essere una funzione. Ad esempio, CalculatePiToNthDigit (n) dovrebbe essere una funzione, poiché in realtà non modifica lo stato dell’object Math a cui è collegato.

Forse è un po ‘vagante, ma in realtà si riduce a decidere quali sono i tuoi oggetti e cosa rappresentano. Se non riesci a capire se dovrebbe essere una proprietà o una funzione, forse non importa quale.

Le proprietà similicamente sono attributi dei tuoi oggetti. I metodi sono comportamenti del tuo object.

Label è un attributo e ha più senso renderlo una proprietà.

In termini di programmazione orientata agli oggetti si dovrebbe avere una chiara comprensione di ciò che è parte del comportamento e ciò che è semplicemente un attributo.

Auto {Colore, modello, marca}

Una macchina ha gli attributi Colore, Modello e Marca quindi non ha senso avere un metodo SetColor o SetModel perché in modo similare non chiediamo a Car di impostare il proprio colore.

Quindi, se si mappa il caso della proprietà / metodo con l’object della vita reale o se lo si guarda dal punto di vista simmetrico, la tua confusione sparirà davvero.

Cercando attraverso MSDN, ho trovato un riferimento su Proprietà vs Metodi che fornisce alcune ottime linee guida per la creazione di metodi:

  • L’operazione è una conversione, ad esempio Object.ToString .
  • L’operazione è abbastanza costosa da consentire all’utente di comunicare all’utente la possibilità di prendere in considerazione il caching del risultato.
  • Ottenere un valore di proprietà utilizzando l’accessi get avrebbe un effetto collaterale osservabile.
  • Chiamare il membro due volte di seguito produce risultati diversi.
  • L’ordine di esecuzione è importante. Si noti che le proprietà di un tipo dovrebbero poter essere impostate e recuperate in qualsiasi ordine.
  • Il membro è statico ma restituisce un valore che può essere modificato.
  • Il membro restituisce un array. Le proprietà che restituiscono gli array possono essere molto fuorvianti. Di solito è necessario restituire una copia dell’array interno in modo che l’utente non possa modificare lo stato interno. Questo, unito al fatto che un utente può facilmente presumere che sia una proprietà indicizzata, porta a un codice inefficiente.

Preferisco usare le proprietà per aggiungere / impostare metodi con 1 parametro. Se i parametri sono più, utilizzare i metodi.

Le proprietà dovrebbero essere solo semplici e ottenere un liner. Qualche cosa in più e dovrebbe davvero essere spostato su un metodo. Il codice complesso dovrebbe sempre essere nei metodi.

Uso solo le proprietà per l’accesso alle variabili, ovvero per ottenere e impostare singole variabili, oppure per ottenere e impostare i dati nei controlli. Non appena è necessario / eseguito qualsiasi tipo di manipolazione dei dati, utilizzo metodi.

Un grande vantaggio per le proprietà è che il valore della proprietà può essere visto in Visual Studio durante il debug.

Le proprietà sono davvero belle perché sono accessibili nel visual designer di Visual Studio, purché abbiano accesso.

Usano essere utilizzati se si sta semplicemente impostando e ottenendo e forse qualche convalida che non accede a una quantità significativa di codice. Fai attenzione perché la creazione di oggetti complessi durante la convalida non è semplice.

Qualsiasi altro metodo è il modo preferito.

Non si tratta solo di semantica. Usando le proprietà inizia in modo inappropriato avere stranezze si verificano nel visual designer visivo dello studio.

Ad esempio, stavo ottenendo un valore di configurazione all’interno di una proprietà di una class. La class di configurazione apre effettivamente un file ed esegue una query sql per ottenere il valore di tale configurazione. Ciò ha causato problemi nella mia applicazione in cui il file di configurazione sarebbe stato aperto e bloccato da Visual Studio stesso piuttosto che dalla mia applicazione perché non stava solo leggendo ma scrivendo il valore di configurazione (tramite il metodo setter). Per risolvere questo problema ho dovuto cambiarlo in un metodo.

Per quanto riguarda la progettazione, le proprietà rappresentano dati o attributi dell’object class, mentre i metodi sono azioni o comportamenti dell’object class.

In .Net, il mondo ci sono altre implicazioni nell’uso delle Proprietà:

  • Le proprietà vengono utilizzate in Databinding, mentre i metodi get_ / set_ no.
  • Proprietà utente di serializzazione XML come meccanismo naturale di serilization.
  • Le proprietà sono accessibili dal controllo PropertyGrid e dall’interno ICustomTypeDescriptor , che può essere utilizzato efficacemente se si sta scrivendo una libreria personalizzata.
  • Le proprietà sono controllate dagli Attributi , si può usare saggiamente per progettare i software orientati agli Aspetti.

Fraintendimenti (IMHO) sull’utilizzo delle proprietà:

  • Utilizzato per esporre piccoli calcoli: il blocco di ControlDesigner.SelectionRules viene eseguito in 72 righe !!
  • Utilizzato per esporre strutture dati interne: anche se una proprietà non si associa a un membro dati interno, è ansible utilizzarla come proprietà, se è un attributo della class. Viceversa, anche se un attributo delle proprietà della class non è consigliabile, restituire dati come membri di dati (invece i metodi sono usati per restituire una copia profonda dei membri).

Nell’esempio qui potrebbe essere stato scritto, con più significato aziendale come:

 public String Title { set { Label.Text = text; } } 

Vengo da java e ho usato get .. set .. metodo per un po ‘.

Quando scrivo codice, non chiedo a me stesso: “l’accesso a questi dati è semplice o richiede un processo pesante?” perché le cose possono cambiare (oggigiorno questa proprietà è semplice, tomonrow può richiedere un processo piuttosto pesante).

Oggi ho un metodo SetAge (int età) tomonrow avrò anche il metodo SetAge (data di nascita) che calcola l’età usando la data di nascita.

Sono rimasto molto deluso dal fatto che il compilatore trasformi la proprietà in get e set ma non consideri i miei metodi Get … e Set .. come lo stesso.

Ecco una buona serie di linee guida per quando utilizzare proprietà vs metodi di Bill Wagner

  • Utilizzare una proprietà quando tutte queste sono vere: i getter dovrebbero essere semplici e quindi improbabili che generino eccezioni. Si noti che questo non implica l’accesso alla rete (o al database). O potrebbe fallire, e quindi genererebbe un’eccezione.
  • Non dovrebbero avere dipendenze l’uno dall’altra. Si noti che questo include l’impostazione di una proprietà e la sua influenza su un’altra. (Ad esempio, l’impostazione della proprietà FirstName influirebbe su una proprietà FullName di sola lettura che ha composto il nome + le proprietà del cognome implica una tale dipendenza)
  • Dovrebbero essere configurabili in qualsiasi ordine
  • Il getter non ha un effetto collaterale osservabile Nota che questa linea guida non preclude alcune forms di valutazione lazy in una proprietà.
  • Il metodo deve sempre tornare immediatamente. (Si noti che ciò preclude una proprietà che effettua una chiamata di accesso al database, una chiamata al servizio web o un’altra operazione simile).
  • Utilizzare un metodo se il membro restituisce un array.
  • Le chiamate ripetute al getter (senza codice di intervento) devono restituire lo stesso valore.
  • Le chiamate ripetute al setter (con lo stesso valore) non dovrebbero produrre alcuna differenza da una singola chiamata.

  • Il risultato non dovrebbe restituire un riferimento alle strutture dati interne (vedere l’articolo 23). Un metodo potrebbe restituire una copia profonda e potrebbe evitare questo problema.

* Tratto dalla mia risposta ad una domanda doppia.