sharp - visual c# get set




C#Proprietà automatiche-Perché devo scrivere? Get; impostato;"? (6)

Il compilatore deve sapere se vuoi che generi un getter e / o un setter, o forse sta dichiarando un campo.

Se sia get sia set sono obbligatori nelle proprietà C #, perché devo preoccuparmi di specificare "get; set;" affatto?


Perché hai bisogno di un modo per distinguerlo dai campi semplici.

È anche utile avere diversi modificatori di accesso, ad es

public int MyProperty { get; private set; }

Beh, ovviamente hai bisogno di un modo per disambiguare i campi e le proprietà. Ma sono necessarie parole chiave davvero necessarie? Ad esempio, è chiaro che queste due dichiarazioni sono diverse:

public int Foo;
public int Bar { }

Potrebbe funzionare. Cioè, è una sintassi che un compilatore potrebbe plausibilmente dare un senso.

Ma poi si arriva a una situazione in cui un blocco vuoto ha un significato semantico. Sembra precario.


Ho pensato di condividere le mie scoperte su questo argomento.

Codificare una proprietà come la seguente, è una chiamata di collegamento .net 3.0 " auto-implementata ".

public int MyProperty { get; set; }

Questo ti risparmia un po 'di battitura. Il lungo modo di dichiarare una proprietà è come questo:

private int myProperty;
public int MyProperty 
{
  get { return myProperty; }
  set { myProperty = value; } 
}

Quando si utilizza la "proprietà auto-implementata" il compilatore genera il codice per eseguire il collegamento e impostare su "k_BackingField". Di seguito è riportato il codice smontato utilizzando Reflector.

public int MyProperty
{
    [CompilerGenerated]
    get
    {
        return this.<MyProperty>k__BackingField;
    }
    [CompilerGenerated]
    set
    {
        this.<MyProperty>k__BackingField = value;
    }
}

codice C # smontato da IL

Inoltre collega un metodo per il setter e il getter.

[CompilerGenerated]
public void set_MyProperty(int value)
{
    this.<MyProperty>k__BackingField = value;
}
[CompilerGenerated]
public int get_MyProperty()
{
    return this.<MyProperty>k__BackingField;
}

codice C # smontato da IL

Quando si dichiara una proprietà auto-implementata in sola lettura, impostando il setter su privato:

 public int MyProperty { get; private set; }

Tutto il compilatore contrassegna il " set " come privato. Il setter e il metodo getter dicono lo stesso.

public int MyProperty
{
    [CompilerGenerated]
    get
    {
        return this.<MyProperty>k__BackingField;
    }
    private [CompilerGenerated]
    set
    {
        this.<MyProperty>k__BackingField = value;
    }
}

codice C # smontato da IL

Quindi non sono sicuro del motivo per cui il framework richiede sia il get; e impostare; su una proprietà auto-implementata. Avrebbero potuto semplicemente non aver scritto il metodo set and setter se non fosse stato fornito. Ma potrebbe esserci qualche problema con il livello del compilatore che rende questo difficile, non lo so.

Se osservi la lunga strada della dichiarazione di una proprietà di sola lettura:

public int myProperty = 0;
public int MyProperty
{
    get { return myProperty; }
}  

E poi guarda il codice smontato. Il setter non è affatto lì.

public int Test2
{
    get
    {
        return this._test;
    }
}

public int get_Test2()
{
    return this._test;
}

codice C # smontato da IL


ERRORE: una proprietà o un indicizzatore non può essere passato come parametro out o ref

Se non hai specificato {get; set;} {get; set;} quindi il compilatore non saprebbe se si tratta di un campo o di una proprietà. Questo è importante perché mentre "sembrano" identici, il compilatore li tratta in modo diverso. Ad es. Chiamare "InitAnInt" sulla proprietà genera un errore.

class Test
{
    public int n;
    public int i { get; set; }
    public void InitAnInt(out int p)
    {
        p = 100;
    }
    public Test()
    {
        InitAnInt(out n); // This is OK
        InitAnInt(out i); // ERROR: A property or indexer may not be passed 
                          // as an out or ref parameter
    }
}

Non dovresti creare campi pubblici / Variabili sulle classi, non sai mai quando vorrai cambiarlo per ottenere e impostare i metodi di accesso, e quindi non sai quale codice stai per interrompere, specialmente se hai client che programmano contro la tua API.

Inoltre è possibile avere diversi modificatori di accesso per ottenere e impostare, ad esempio {get; set privato ;} rende pubblico e l'insieme privato alla classe dichiarante.


Perché potresti volere una proprietà di sola lettura:

public int Foo { get; private set; }

O proprietà Write-only:

public int Foo { private get; set; }




automatic-properties