2013-03-31 14 views

Odpowiedz

29

readonly oznacza, że ​​przypisanie pola może wystąpić tylko w pobliżu deklaracji pola lub wewnątrz konstruktora. Więc można użyć IsInitOnly nieruchomość na FieldInfo, który

Pobiera wartość wskazującą, czy pole może być ustawiony tylko w ciele konstruktora

Więcej szczegółów na IsInitOnly MSDN article

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

Uwagi: można także użyć właściwości IsLiteral, aby sprawdzić, czy pole jest skompilowane jako stała czasowa. Zwróci false w polu readonly, ale prawdziwe w przypadku pól oznaczonych const.

Kolejna uwaga: odbicie nie zapobiega zapisywaniu w polu readonly i private (to samo dotyczy public readonly, ale chcę wyświetlić bardziej ograniczony przypadek). Więc następnym przykłady kodu są ważne i nie będzie rzucać żadnych wyjątków:

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

Teraz, jeśli masz pole i zapisać wartość dla niego (ja używam BindingFlags dostać pól niestatyczny prywatne, ponieważ GetField won” t powrót FieldInfo dla pól prywatnych domyślnie)

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 

Wszystko działa ok. Zgłasza wyjątek tylko wtedy, gdy pole to const.

+0

jakiś pomysł co 'NonPublic' flaga jest tu robisz? – nawfal

+0

@nawfal 'GetField' domyślnie nie zwraca prywatnych pól. Musisz to wyraźnie ustawić –

+0

@Oh tak, rozumiem. Nie zauważyłem twojego przykładu na temat "prywatny". Dziękuję – nawfal

1

f.Attributes powinna zawierać FieldAttributes.InitOnly