2016-05-28 64 views
9

Esistono differenze tra il modificatore di sola lettura e le proprietà get-only?C# readonly contro Get

esempio:

public class GetOnly 
{ 
    public string MyProp {get; } 
} 

public class ReadOnly 
{ 
    public readonly string MyProp; 
} 

Bonus: c'è un modo per fare un'interfaccia che funziona con entrambi? (da utilizzare con generici)

public interface ISomething 
{ 
    public string MyProp { get; }; 
} 

public class GetOnly : ISomething 
{ 
    public string MyProp {get; } 
} 

public class ReadOnly : ISomething //cannot implement 
{ 
    public readonly string MyProp; 
} 

Molte grazie in anticipo!

+0

È possibile implementare l'interfaccia sulla classe ReadOnly con un'implementazione esplicita –

risposta

7

A prima vista, la proprietà e il campo sono funzionalmente equivalenti e per i normali casi di utilizzo di memorizzazione dei dati e del loro trasferimento non c'è molta differenza nell'utilizzo.

Ma sembra che tu abbia già riscontrato un problema importante: solo le proprietà possono far parte di un'interfaccia.

c'è un modo per creare un'interfaccia che funzioni con entrambi?

No.

Inoltre, molte API che si basano sulla riflessione (EF, serializzazione) esaminare in modo specifico per le proprietà.

+0

Eccellente! Stavo cercando di vedere quale sarebbe stato più leggero nella memoria e mi sono imbattuto in questo cercando di rendere le cose più ASCIUTTE. – robjam

+0

@robjam se si prende in considerazione l'utilizzo di variabili readonly invece di ottenere solo proprietà, si dovrebbe prendere in considerazione l'idea di non utilizzare alcun metodo e di avere solo un void statico main (ottenere il sarcasm?). Una proprietà get only è un campo readonly privato e un vuoto pubblico che restituisce il valore. Nient'altro. - http://tryroslyn.azurewebsites.net/#K4Zwlgdg5gBAygTxAFwKYFsB0BhA9gG31QGNkxcIRMBxVCVAJzGIG4AoUSWRFDTAGUgBHdp2jwkadOzYAHYACN8zGMXwBDECBjYYAbzZsYxmPKUrIyGAA99UVMhYBfNk6A== – Mafii

+0

Hai dimenticato 2 punti importanti: 1) proprietà possono far parte non solo di un'interfaccia, ma anche di una classe base, e può essere ignorato in una catena gerarchica da una classe all'altra. 2) Solo le proprietà possono essere utilizzate come origini in un binding WPF. –

1

Nella parte che segue:

public class GetOnly 
{ 
    public string MyProp {get; } 
} 

MyProp è un property. Tuttavia, in questa parte:

public class ReadOnly 
{ 
    public readonly string MyProp; 
} 

MyProp è un field. Queste sono due cose diverse.

c'è un modo per creare un'interfaccia che funzioni con entrambi?

No. Solo le proprietà possono essere inserite nelle interfacce. I campi non possono

2

Uno è un campo (readonly); l'altro è una proprietà. Le interfacce non possono definire campi, solo proprietà, metodi, indicizzatori ed eventi.

Entrambi possono essere assegnati solo tramite l'inizializzazione del costruttore o del campo e non possono essere modificati successivamente.

+0

@downvoter, per favore lascia un commento su cosa c'è di sbagliato nella mia risposta; Lo migliorerò volentieri se i tuoi suggerimenti sono validi. – CoolBots

+0

@HenkHolterman Ho modificato la mia risposta (in riferimento a 'private set') in base alla risposta. Grazie! – CoolBots

6

Stai fondamentalmente fraintendendo il significato di entrambe le definizioni. Solo esporre il getter dice niente sul fatto che un valore sia o meno di sola lettura.

Mentre in questo esempio banale:

public class GetOnly 
{ 
    public string MyProp { get; } 
} 

possiamo dire che sarà MyPropmai cambiare il suo valore, non possiamo dire sempre che una proprietà getter-solo non avrà cambiato il suo valore. Un esempio di ciò è una situazione in cui noi non è possibile vedere l'implementazione di GetOnly e conoscere solo la definizione pubblica - Ad esempio, se si stesse lavorando con una libreria di terze parti a codice chiuso.

Un esempio più chiaro è questo:

public interface ISomething 
{ 
    string MyProp { get; } 
} 

Questa interfaccia non dice che MyProp è di sola lettura. Si dice che si non è possibile modificare la proprietà. Non dice nulla sul comportamento della proprietà. Ancora peggio, dice solo che non è possibile modificare la proprietà quando si esegue espressamente il casting come ISomething.

E 'tutto possibile implementare l'interfaccia in questo modo (anche se l'interfaccia espone solo il getter):

public class GetOnly : ISomething 
{ 
    public string MyProp { get; set; } 
} 

readonly è un modificatore che rafforza in modo esplicito il fatto che il valore non cambierà mai , tranne nella dichiarazione o nel costruttore (salvo soluzioni alternative come reflection).

Tuttavia, readonly non può funzionare sulle proprietà, poiché le proprietà sono semplicemente zucchero sintattico per ottenere/impostare metodi . Inoltre, le interfacce definiscono solo i metodi e pertanto non è possibile definire campi (e per estensione, campi readonly).

Quindi per rispondere alla tua risposta: Sì, sono mondi a parte, e sono solo simili in superficie.