2013-03-31 2 views

ответ

29

readonly означает, что назначение поля может происходить только вблизи объявления поля или внутри конструктора. Таким образом, вы можете использовать IsInitOnly собственность на FieldInfo, который

Получает значение, указывающее, является ли данное поле может быть установлен только в теле конструктора

Более подробная информация на IsInitOnly MSDN article

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

Примечания: вы также можете использовать свойство IsLiteral, чтобы проверить, является ли поле скомпилированной постоянной времени. Он вернет false для поля readonly, но верно для полей, помеченных const.

Другое примечание: отражение не мешает вам писать в поле readonly и private (то же самое верно для public readonly, но я хочу показать более ограниченный случай). Таким образом, следующие примеры кода являются действительными и не будут бросать никаких исключений:

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

Теперь, если вы получите поле и написать ему значение (я использую BindingFlags получить частные нестатические поля, потому что GetField воны» т возвращение FieldInfo для частных полей по умолчанию)

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 

Все работает нормально. Он генерирует исключение, только если поле const.

+0

Любая идея, что 'NonPublic' флаг делает здесь? – nawfal

+0

@nawfal 'GetField' по умолчанию не возвращает частные поля. Вам нужно установить это явно –

+0

@ О, да, я понял. Я не заметил вашего примера о 'private'. Спасибо – nawfal