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
.
Любая идея, что 'NonPublic' флаг делает здесь? – nawfal
@nawfal 'GetField' по умолчанию не возвращает частные поля. Вам нужно установить это явно –
@ О, да, я понял. Я не заметил вашего примера о 'private'. Спасибо – nawfal