2009-07-30 18 views
12

Sono nuovo nel mondo .NET che proviene dal C++ e sto cercando di capire meglio le proprietà. Ho notato che nel framework .NET Microsoft usa le proprietà dappertutto. C'è un vantaggio nell'usare le proprietà piuttosto che creare metodi get/set? Esiste una linea guida generale (oltre alla convenzione sui nomi) per quando si dovrebbero usare le proprietà?Quando utilizzare Proprietà e metodi?

risposta

11

Si tratta di puro zucchero sintattico. Nel back-end, è compilato in semplici metodi get e set.

Usalo per convenzione e sembra più bello.

Alcune linee guida indicano che quando si presenta un rischio elevato di lancio di Eccezioni o di errori, non utilizzare le proprietà ma getter/setter espliciti. Ma generalmente anche allora vengono usati.

+1

Questo probabilmente non è quello che volevi dire, ma io secondo la "sembra più bello" parte. Prima della convention (quando ero un noob!), Ho usato le proprietà perché l'icona IntelliSense sembrava più interessante. –

+0

Haha. Ma stiamo parlando di metodi vs proprietà, non campi vs proprietà. – Dykam

+0

Non sono d'accordo, le proprietà offrono un buon livello di astrazione. Non sono solo zucchero sintattico. – Matt

2

proprietà sono get metodi/set

0

Il compilatore emette effettivamente i metodi get_MyProperty e set_MyProperty per ogni proprietà definita.

7

Proprietà sono metodi get/set; semplicemente, li formalizza in un unico concetto (in lettura e scrittura), consentendo (per esempio) metadati contro la struttura, anziché singoli membri. Ad esempio:

[XmlAttribute("foo")] 
public string Name {get;set;} 

Questa è una coppia di metodi get/set, ma i metadati aggiuntivi si applicano a entrambi. Inoltre, IMO, rende semplicemente più facile da usare:

someObj.Name = "Fred"; // clearly a "set" 
DateTime dob = someObj.DateOfBirth; // clearly a "get" 

Non abbiamo duplicato il fatto che stiamo facendo un get/set.

Un'altra cosa bella è che consente il collegamento dati bidirezionale semplice contro la proprietà ("Nome" sopra), senza fare affidamento su alcun modello magico (eccetto quelli garantiti dal compilatore).

6

C'è un intero libro dedicato a rispondere a questo tipo di domande: Linee guida per la progettazione di framework da Addison-Wesley. Vedere la sezione 5.1.3 per consigli su quando scegliere una proprietà rispetto a un metodo.

Gran parte del contenuto di questo libro è disponibile anche su MSDN, ma trovo comodo averlo sulla mia scrivania.

+0

riferimento libro interessante, che potrebbe essere v utile grazie – TooTone

2

proprietà sono impostate e ottenere metodi come la gente qui intorno hanno spiegato, ma l'idea di avere loro sta facendo questi metodi gli unici che giocano con i valori privati ​​(ad esempio, per gestire le convalide).

Tutta l'altra logica dovrebbe essere fatta contro le proprietà, ma è sempre più facile lavorare mentalmente con qualcosa che puoi gestire come un valore sul lato sinistro e destro delle operazioni (proprietà) e non dover nemmeno pensare che sia un metodo.

Personalmente ritengo che è l'idea principale dietro proprietà.

2

Ho sempre pensato che le proprietà sono i nomi di una classe, dove, come i metodi sono i verbi ...

1

Le proprietà consentono semplicemente di risparmiare un po 'di tempo dalla scrittura dello standard di stampa che accompagna i metodi get/set.

Detto questo, un sacco di roba .NET gestisce le proprietà in modo diverso, ad esempio una griglia visualizza automaticamente le proprietà ma non visualizza una funzione equivalente.

Questo è utile, perché è possibile eseguire metodi get/set per le cose che non si desidera visualizzare e le proprietà per quelle che si desidera visualizzare.

0

Sebbene non sia una regola difficile e veloce e, come altri hanno sottolineato, le proprietà vengono implementate come coppie Get/Set "dietro le quinte" - in genere Proprietà superficie incapsulata/protetta dati di stato mentre i metodi (ovvero Procedure o Funzioni) lavora e produce il risultato di quel lavoro.

Poiché tali metodi richiedono spesso argomenti che potrebbero semplicemente consumare ma possono anche ritornare in uno stato alterato o possono produrre un nuovo oggetto o valore come risultato del lavoro svolto.

In generale - se avete bisogno di un modo di controllare l'accesso ai dati o stato quindi proprietà consentono l'implementazione che l'accesso in modo definito, validabile e ottimizzata (permettendo restrizione di accesso, gamma & il controllo degli errori, la creazione di supporto-store su richiesta e un modo per evitare chiamate di impostazioni ridondanti).

Al contrario, i metodi trasformano lo stato e danno origine a nuovi valori internamente ed esternamente senza risultati necessariamente ripetibili.

Certamente se ti ritrovi a scrivere codice procedurale o di trasformazione in una proprietà, probabilmente stai davvero scrivendo un metodo.

0

Si noti inoltre che le proprietà sono disponibili tramite riflessione. Anche se i metodi sono, le proprietà rappresentano "qualcosa di interessante" sull'oggetto. Se stai provando a visualizzare una griglia di proprietà di un oggetto, ad esempio qualcosa come la finestra di progettazione di Visual Studio, puoi utilizzare la reflection per interrogare le proprietà di una classe, scorrere tra tutte le proprietà e interrogare l'oggetto per la sua valore.

2

Prima di tutto, la convenzione di denominazione è: utilizzare PascalCase per il nome della proprietà, proprio come con i metodi. Inoltre, le proprietà non dovrebbero contenere operazioni molto complesse. Questi dovrebbero essere mantenuti nei metodi.

In OOP, si descrive un oggetto con attributi e funzionalità. Lo fai quando progetti una classe. Prendi in considerazione la progettazione di un'auto. Esempi di funzionalità potrebbero essere la possibilità di spostarsi da qualche parte o attivare i tergicristalli. All'interno della tua classe, questi sarebbero metodi. Un attributo sarebbe il numero di passeggeri all'interno dell'auto in un dato momento. Senza di proprietà, si dovrebbe avere due modi per implementare l'attributo:

fare un pubblico variabile:

// class Car 
public int passengerCount = 4; 

// calling code 
int count = myCar.passengerCount; 

Questo ha diversi problemi. Prima di tutto, non è davvero un attributo del veicolo. Devi aggiornare il valore dall'interno della classe Car per far sì che rappresenti il ​​vero stato dei veicoli. In secondo luogo, la variabile è pubblica e potrebbe anche essere scritta in.

La seconda variante è una widley utilizzata, e. g. in Java, dove non si hanno proprietà come in C#:

Utilizzare un metodo per incapsulare il valore e magari eseguire prima alcune operazioni.

// class Car 
public int GetPassengerCount() 
{ 
    // perform some operation 
    int result = CountAllPassengers(); 

    // return the result 
    return result; 
} 

// calling code 
int count = myCar.GetPassengerCount(); 

In questo modo si riesce a risolvere i problemi con una variabile pubblica. Chiedendo il numero di passeggeri, puoi essere sicuro di ottenere il risultato più recente da quando lo hai ricontato prima di rispondere. Inoltre, non è possibile modificare il valore poiché il metodo non lo consente. Il problema è, tuttavia, che in realtà volevi che la quantità di passeggeri fosse un attributo, non una funzione della tua auto.

Il secondo approccio non è necessariamente sbagliato, semplicemente non è corretto. Ecco perché alcune lingue includono modi per far apparire gli attributi come variabili, anche se funzionano come metodi dietro le quinte. Actionscript, ad esempio, include anche la sintassi per definire i metodi a cui si accede in uno stile variabile dal codice chiamante.

Ricordare che ciò comporta anche responsabilità. L'utente chiamante si aspetta che si comporti come un attributo, non una funzione. quindi, se solo chiedi a una macchina quanti passeggeri ha bisogno di 20 secondi per caricarlo, probabilmente dovresti comprimerlo in un metodo reale, dal momento che il chiamante si aspetta che le funzioni richiedano più tempo rispetto all'accesso a un attributo.

MODIFICA: Ho quasi dimenticato di dirlo: la possibilità di eseguire determinati controlli prima di consentire l'impostazione di una variabile. Usando semplicemente una variabile pubblica, potresti praticamente scrivere qualcosa in esso. Il metodo setter o proprietà ti danno la possibilità di controllarlo prima di salvarlo effettivamente.

0

Pensateci in questo modo, Proprietà incapsula i vostri campi (comunemente contrassegnati come privati) mentre allo stesso tempo fornisce ai vostri colleghi sviluppatori di impostare o ottenere il valore del campo. Puoi anche eseguire la convalida di routine nel metodo set della proprietà, se lo desideri.

0

Proprietà non sono solo zucchero sintattico - sono importanti, se è necessario creare mappature relazionali a oggetti (Linq2Sql o Linq2Entities), perché si comportano proprio come le variabili, mentre è possibile nascondere i dettagli di implementazione del object mappatura relazionale (persistenza). È anche possibile convalidare un valore che gli viene assegnato nel getter della proprietà e proteggerlo dall'assegnazione di valori indesiderati.

Non è possibile farlo con la stessa eleganza con i metodi. Penso che sia meglio dimostrarlo con un esempio pratico.

In uno dei suoi articoli, Scott Gu crea classi associate al database Northwind utilizzando l'approccio "code first". Un breve esempio tratto dal blog di Scott (con una piccola modifica, l'articolo completo può essere letto in blog di Scott Gu here):

public class Product 
{ 
    [Key] 
    public int ProductID { get; set; } 

    public string ProductName { get; set; } 
    public Decimal? UnitPrice { get; set; } 
    public bool Discontinued { get; set; } 
    public virtual Category category { get; set; } 
} 

// class Category omitted in this example 

public class Northwind : DbContext 
{ 
    public DbSet<Product> Products { get; set; } 
    public DbSet<Category> Categories { get; set; } 
} 

È possibile utilizzare entità imposta Products, Categories e le relative classi Product e Category altrettanto se fossero oggetti normali contenenti variabili: puoi leggerli e scriverli e si comportano proprio come le normali variabili. Ma puoi anche usarli nelle query di Linq, persisterli (memorizzarli nel database e recuperarli). Nota anche come è facile utilizzare annotations (attributi C#) per definire la chiave primaria (in questo esempio ProductID è la chiave primaria per Product).

Mentre le proprietà sono usati per definire una rappresentazione dei dati memorizzati nel database, ci sono alcuni metodi definiti nella classe set entità che controllano la persistenza: Ad esempio, il metodo Remove() segna un data entità cancellata, mentre Add() aggiunge una determinata entità, SaveChanges() rende permanenti le modifiche. È possibile considerare i metodi come azioni (ad esempio, si controlla ciò che si desidera fare con i dati).

Infine Vi do un esempio di come, naturalmente, è possibile utilizzare queste classi:

// instantiate the database as object 
var nw = new NorthWind(); 

// select product 
var product = nw.Products.Single(p => p.ProductName == "Chai"); 

// 1. modify the price 
product.UnitPrice = 2.33M; 

// 2. store a new category 
var c = new Category(); 
c.Category = "Example category"; 
c.Description = "Show how to persist data"; 
nw.Categories.Add(c); 

// Save changes (1. and 2.) to the Northwind database 
nw.SaveChanges(); 
Problemi correlati