Подтвердить что ты не робот

Как найти переменную-член только для чтения?

class Bla
{
    public readonly int sum;
}

FieldInfo f = type.GetField("sum");
f.??   // what?

Как найти, если sum только для чтения или нет? Для свойств я могу сделать PropertyInfo.CanWrite, чтобы узнать, имеет ли член доступ к записи.

4b9b3361

Ответ 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.

Ответ 2

f.Attributes должен содержать FieldAttributes.InitOnly