2012-06-22 5 views
29

Non riesco a capire il concetto di getter e setter nel linguaggio C#. In linguaggi come Objective-C, sembrano parte integrante del sistema, ma non tanto in C# (per quanto posso dire allo). Ho già letto libri e articoli, quindi la mia domanda è, per quelli di voi che comprendono i getters & setter in C#, quale esempio usereste personalmente se si insegnasse il concetto a un principiante assoluto (questo includerebbe come poche righe di codice possibile)?Cercare un esempio breve e semplice di getter/setter in C#

+0

Questo è abbastanza ampia. In particolare, cosa ti dà problemi con le proprietà C#? – arcain

+0

Questo è * probabilmente * un duplicato di http://stackoverflow.com/questions/1209359/properties-and-methods – arcain

+0

Mi chiedo cosa manca a getter/setter in C# rispetto all'obiettivo C? – Vlad

risposta

13

In C#, Properties rappresentano i tuoi getter e setter.

Ecco un esempio:

public class PropertyExample 
{ 
    private int myIntField = 0; 

    public int MyInt 
    { 
     // This is your getter. 
     // it uses the accessibility of the property (public) 
     get 
     { 
      return myIntField; 
     } 
     // this is your setter 
     // Note: you can specifiy different accessibility 
     // for your getter and setter. 
     protected set 
     { 
      // You can put logic into your getters and setters 
      // since they actually map to functions behind the scenes 
      DoSomeValidation(value) 
      { 
       // The input of the setter is always called "value" 
       // and is of the same type as your property definition 
       myIntField = value; 
      } 
     } 
    } 
} 

Si potrebbe accedere a questa proprietà, proprio come un campo. Per esempio:

PropertyExample example = new PropertyExample(); 
example.MyInt = 4; // sets myIntField to 4 
Console.WriteLine(example.MyInt); // prints 4 

Poche altre cose da notare: 1) Non è necessario in modo da precisare sia un getter e setter, è possibile omettere uno dei due.

2) Le proprietà sono solo "zucchero sintattico" per getter e setter tradizionali. Il compilatore creerà effettivamente le funzioni get_ e set_ dietro le quinte (nell'IL compilato) e mapperà tutti i riferimenti alla tua proprietà a quelle funzioni.

11

La maggior parte dei linguaggi funziona in questo modo e lo si può fare anche in C#.

public void setRAM(int RAM) 
    { 
     this.RAM = RAM; 
    } 
    public int getRAM() 
    { 
     return this.RAM; 
    } 

Ma C# dà anche una soluzione più elegante a questo:

public class Computer 
    { 
     int ram; 
     public int RAM 
     { 
      get 
      { 
        return ram; 
      } 
      set 
      { 
        ram = value; // value is a reserved word and it is a variable that holds the input that is given to ram (like in the example below) 
      } 
     } 
    } 

E l'accesso in seguito con.

Computer comp = new Computer(); 
    comp.RAM = 1024; 
    int var = comp.RAM; 

Per le versioni più recenti di C# è ancora meglio:

public class Computer 
{ 
    public int RAM { get; set; } 
} 

e versioni successive:

Computer comp = new Computer(); 
comp.RAM = 1024; 
int var = comp.RAM; 
+0

Grazie per aver spiegato che valore è effettivamente – jskidd3

1

esempio semplice

public class Simple 
    { 
     public int Propery { get; set; } 
    } 
1

Per quanto ho capito getter e setter sono per migliorare l'incapsulamento. Non c'è niente di complesso in C#.

si definisce una proprietà di in oggetto come questo:

int m_colorValue = 0; 
public int Color 
{ 
    set { m_colorValue = value; } 
    get { return m_colorValue; } 
} 

Questa è l'uso più semplice. Fondamentalmente imposta una variabile interna o ne recupera il valore. si utilizza una proprietà come questa:

someObject.Color = 222; // sets a color 222 
int color = someObject.Color // gets the color of the object 

Si potrebbe eventualmente fare un po 'di elaborazione sul valore nei setter o getter in questo modo:

public int Color 
{ 
    set { m_colorValue = value + 5; } 
    get { return m_colorValue - 30; } 
} 

se si salta impostare o ottenere, la vostra proprietà sarà leggere o scrivere solo È così che capisco le cose.

3

C# presenta proprietà che fanno la maggior parte del lavoro pesante per voi ...

cioè

public string Name { get; set; } 

è un C# scorciatoia per la scrittura ...

private string _name; 

public string getName { return _name; } 
public void setName(string value) { _name = value; } 

Fondamentalmente getter e i setter sono solo mezzi per aiutare l'incapsulamento. Quando crei una classe, hai diverse variabili di classe che forse vuoi esporre ad altre classi per consentire loro di dare un'occhiata ad alcuni dei dati che archivi. Anche se rendere pubbliche le variabili all'inizio può sembrare un'alternativa accettabile, a lungo termine rimpiangerai che altre classi manipolino direttamente le variabili dei membri delle classi. Se li costringi a farlo attraverso un setter, puoi aggiungere la logica per assicurarti che non si verifichino mai strani valori, e puoi sempre cambiare quella logica in futuro senza influenzare le cose che già manipolano questa classe.

cioè

private string _name; 

public string getName { return _name; } 
public void setName(string value) 
{ 
    //Don't want things setting my Name to null 
    if (value == null) 
    { 
     throw new InvalidInputException(); 
    } 
    _name = value; 
} 
+0

ignorare il setter in caso di input errato di solito è una cattiva idea – Vlad

+0

Probabilmente ok per un semplice esempio, ma ho modificato un'eccezione piuttosto che un'ignorazione silenziosa. –

0

Internamente, getter e setter sono solo metodi. Quando C# compila, genera i metodi per i tuoi getter e setter come questo, ad esempio:

public int get_MyProperty() { ... } 
public void set_MyProperty(int value) { ... } 

C# permette di dichiarare questi metodi utilizzando una sintassi breve mano. La riga sottostante verrà compilata nei metodi sopra riportati quando crei la tua applicazione.

public int MyProperty { get; set; } 

o

private int myProperty; 
public int MyProperty 
{ 
    get { return myProperty; } 
    set { myProperty = value; } // value is an implicit parameter containing the value being assigned to the property. 
} 
0

getter e setter in C# sono qualcosa che semplifica il codice.

private string name = "spots"; 

public string Name 
{ 
    get { return name; } 
    set { name = value; } 
} 

e chiamandolo (supponiamo di avere una persona obj con una proprietà nome):

Console.WriteLine(Person.Name); //prints "spots" 
Person.Name = "stops"; 
Console.Writeline(Person.Name); //prints "stops" 

Questo semplifica il codice. Dove in Java potresti dover avere due metodi, uno per ottenere() e uno per impostare() la proprietà, in C# è tutto fatto in un punto. Io di solito faccio all'inizio dei miei corsi:

public string foobar {get; set;} 

Questo crea un getter e setter per la mia proprietà foobar. Chiamarlo è lo stesso modo mostrato in precedenza. È necessario notare che non è necessario includere sia get che set. Se non vuoi che la proprietà venga modificata, non includere il set!

41

penso che un po 'di codice contribuirà a illustrare ciò che setter e getter sono:

public class Foo 
{ 
    private string bar; 

    public string GetBar() 
    { 
     return bar; 
    } 

    public void SetBar(string value) 
    { 
     bar = value; 
    } 
} 

In questo esempio abbiamo un membro privato della classe che si chiama bar. I metodi GetBar e SetBar fanno esattamente ciò che vengono chiamati: uno recupera il membro della barra e l'altro ne imposta il valore.

In C# 1.1 + hai proprietà. La funzionalità di base è la stessa:

public class Foo 
{ 
    private string bar; 

    public string Bar 
    { 
     get { return bar; } 
     set { bar = value; } 
    } 
} 

La barra dei membri privati ​​non è accessibile al di fuori della classe. Tuttavia la "barra" pubblica è, e ha due accessors - get, che proprio come nell'esempio sopra "GetBar()" restituisce il membro privato, e anche un set - che corrisponde al metodo SetBar (valore stringa) nella parte precedente esempio.

A partire da C# 3.0 e sopra il compilatore è stato ottimizzato al punto in cui tali proprietà non hanno bisogno di avere il membro privato come fonte. Il compilatore genera automaticamente un membro privato di quel tipo e lo utilizza come origine di una proprietà.

public class Foo 
{ 
    public string Bar { get; set; } 
} 

ciò che il codice mostra è una proprietà automatica che ha un membro privato generato dal compilatore. Non vedi il membro privato ma è lì. Ciò ha anche introdotto un paio di altri problemi, principalmente con il controllo degli accessi. In C# 1.1, e 2.0 è possibile omettere la porzione di ottenere o impostare di una proprietà:

public class Foo 
{ 
    private string bar; 

    public string Bar 
    { 
     get{ return bar; } 
    } 
} 

Dandovi la possibilità di limitare come altri oggetti interagiscono con il "Bar" di proprietà della classe Foo. A partire con C# 3.0 e versioni successive - se si è scelto di utilizzare le proprietà automatiche si dovrà specificare l'accesso alla proprietà come segue:

public class Foo 
{ 
    public string Bar { get; private set; } 
} 

Ciò significa che solo la classe stessa può impostare Bar per un certo valore, comunque chiunque potrebbe leggere il valore in Bar.

3

La mia spiegazione sarebbe seguente. (Non è così breve, ma è abbastanza semplice.)


Immaginate una classe con una variabile:

class Something 
{ 
    int weight; 
    // and other methods, of course, not shown here 
} 

Beh, c'è un piccolo problema con questa classe: nessuno può vedere la weight . Potremmo rendere pubblico weight, ma poi tutti sarebbe in grado di cambiare il weight in qualsiasi momento (che forse non è quello che vogliamo). Quindi, bene, possiamo fare una funzione:

class Something 
{ 
    int weight; 
    public int GetWeight() { return weight; } 
    // and other methods 
} 

questo è già meglio, ma ora tutti, invece di pianura something.Weight deve digitare something.GetWeight(), che è, beh, brutto.

Con le proprietà, possiamo fare lo stesso, ma il codice rimane pulito:

class Something 
{ 
    public int weight { get; private set; } 
    // and other methods 
} 

int w = something.weight // works! 
something.weight = x; // doesn't even compile 

Nizza, quindi con le proprietà abbiamo un controllo più preciso sul accesso variabile.

altro problema: va bene, vogliamo che il codice esterno per essere in grado di impostare weight, ma vorremmo per controllare il suo valore, e non permettere i pesi inferiori a 100. Inoltre, ci sono sia qualche altra variabile interna density , che dipende da weight, quindi vorremmo ricalcolare il density non appena le modifiche weight.

Ciò si ottiene tradizionalmente nel seguente modo:

class Something 
{ 
    int weight; 
    public int SetWeight(int w) 
    { 
     if (w > 100) 
      throw new ArgumentException("weight too small"); 
     weight = w; 
     RecalculateDensity(); 
    } 
    // and other methods 
} 

something.SetWeight(anotherSomething.GetWeight() + 1); 

Ma ancora una volta, non vogliamo esporre ai nostri clienti che l'impostazione del peso è un'operazione complicata, è semanticamente nient'altro che l'assegnazione di un nuovo peso. Quindi, il codice con un setter guarda allo stesso modo, ma è più bello:

class Something 
{ 
    private int _w; 
    public int Weight 
    { 
     get { return _w; } 
     set 
     { 
      if (value > 100) 
       throw new ArgumentException("weight too small"); 
      _w = value; 
      RecalculateDensity(); 
     } 
    } 
    // and other methods 
} 

something.Weight = otherSomething.Weight + 1; // much cleaner, right? 

Quindi, senza dubbio, le proprietà sono "solo" uno zucchero sintattico. Ma rende il codice del cliente migliore. È interessante notare che la necessità di cose simili alla proprietà si presenta molto spesso, è possibile verificare la frequenza con cui si trovano le funzioni come GetXXX() e SetXXX() nelle altre lingue.

+0

questo è un superbo esempio per il mio stile di apprendimento – CM90

+1

@ CM90: grazie! :) – Vlad

+0

Really Nice Explanation :) –

1

bene qui è uso comune di getter nel caso in cui l'uso effettivo,

public class OrderItem 
{ 
public int Id {get;set;} 
public int quantity {get;set;} 
public int Price {get;set;} 
public int TotalAmount {get {return this.quantity *this.Price};set;} 
} 
0

Questo è un esempio di base di un oggetto "articolo" con getter e setter:

public class Article 
    { 

     public String title; 
     public String link; 
     public String description; 

     public string getTitle() 
     { 
      return title; 
     } 

     public void setTitle(string value) 
     { 
      title = value; 
     } 

     public string getLink() 
     { 
      return link; 
     } 

     public void setLink(string value) 
     { 
      link = value; 
     } 
     public string getDescription() 
     { 
      return description; 
     } 

     public void setDescription(string value) 
     { 
      description = value; 
     } 
    } 
+0

La cosa meno bella qui è che le variabili stesse sono rese pubbliche, il che è un pessimo paradigma OO. Soprattutto quando hai setter e getter espliciti accanto ad esso. Molto meglio è implementare il paradigma C#: public String Title {get; impostato}; (lo stesso vale per le altre 2 variabili). Questo incapsula la variabile privata (non visibile, ma generata) dal mondo esterno. – GeertVc