2013-03-31 4 views

risposta

29

readonly significa che l'assegnazione del campo può avvenire solo vicino alla dichiarazione del campo o all'interno di un costruttore. Così si può utilizzare IsInitOnly proprietà su un FieldInfo, che

Ottiene un valore che indica se il campo può essere impostato solo nel corpo del costruttore

Maggiori dettagli sono sul IsInitOnly MSDN article

FieldInfo f = typeof(Bla).GetField("sum"); 
Console.WriteLine(f.IsInitOnly); //return true 

Note: è anche possibile utilizzare la proprietà IsLiteral per verificare se il campo viene compilato con una costante di tempo. Restituirà false per il campo readonly, ma vero per i campi, contrassegnati con const.

Un'altra nota: la riflessione non impedisce di scrivere nel campo readonly e private (lo stesso è vero per public readonly, ma voglio mostrare un caso più limitato). Quindi, gli esempi di codice seguenti sono valide e non buttare eccezioni:

class Bla 
{ 
    //note field is private now 
    private readonly int sum = 0; 
} 

Ora, se si ottiene il campo e scrivere un valore ad essa (io uso BindingFlags per ottenere campi non statici privati, perché GetField vinto' t ritorno FieldInfo per i campi privati ​​per default)

FieldInfo field = typeof(Bla).GetField("sum", BindingFlags.NonPublic | 
               BindingFlags.Instance); 

var bla = new Bla(); 
field.SetValue(bla, 42); 

Console.WriteLine(field.GetValue(bla)); //prints 42 

Tutto funziona bene. Genera un'eccezione solo se un campo è const.

+0

Qualsiasi idea di cosa 'bandiera NonPublic' sta facendo qui? – nawfal

+0

@nawfal 'GetField' non restituirà i campi privati ​​per impostazione predefinita. È necessario impostare questo in modo esplicito –

+0

@Oh sì, ho capito. Non avevo notato il tuo esempio di 'privato'. Grazie – nawfal

1

f.Attributes dovrebbe contenere FieldAttributes.InitOnly