Ответ 1
readonly
означает, что присвоение поля может происходить только вблизи объявления поля или внутри конструктора. Таким образом, вы можете использовать свойство IsInitOnly
на FieldInfo
, которое
Получает значение, указывающее, может ли поле быть задано только в теле конструктора
Подробнее см. IsInitOnly
Статья MSDN
FieldInfo f = typeof(Bla).GetField("sum");
Console.WriteLine(f.IsInitOnly); //return true
Заметки: вы также можете использовать свойство IsLiteral
для проверки, является ли поле скомпилированной постоянной времени. Он вернет false для поля readonly
, но true для полей, помеченных 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
.