Исследование полей и свойств с помощью рефлексии

Последнее обновление: 17.02.2022

Получение информации о полях

Для извлечения всех полей применяется метод GetFields(), который возвращает массив объектов класса FieldInfo.

Некоторые основные свойства и методы класса FieldInfo:

  • Свойство IsFamily: возвращает true, если поле имеет модификатор доступа protected

  • Свойство IsFamilyAndAssembly: возвращает true, если поле имеет модификатор доступа private protected

  • Свойство IsFamilyOrAssembly: возвращает true, если поле имеет модификатор доступа protected internal

  • Свойство IsAssembly: возвращает true, если поле имеет модификатор доступа internal

  • Свойство IsPrivate: возвращает true, если поле имеет модификатор доступа private

  • Свойство IsPublic: возвращает true, если поле имеет модификатор доступа public

  • Свойство IsStatic: возвращает true, если поле статическое

  • Метод GetValue(): возвращает значение поля

  • Метод SetValue(): устанавливает значение поля

Например, получим все поля класса:

using System.Reflection;

Type myType = typeof(Person);

Console.WriteLine("Поля:");
foreach (FieldInfo field in myType.GetFields(
    BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static))
{
    string modificator = "";

    // получаем модификатор доступа
    if (field.IsPublic)
        modificator += "public ";
    else if (field.IsPrivate)
        modificator += "private ";
    else if (field.IsAssembly)
        modificator += "internal ";
    else if (field.IsFamily)
        modificator += "protected ";
    else if (field.IsFamilyAndAssembly)
        modificator += "private protected ";
    else if (field.IsFamilyOrAssembly)
        modificator += "protected internal ";

    // если поле статическое
    if (field.IsStatic) modificator += "static ";

    Console.WriteLine($"{modificator}{field.FieldType.Name} {field.Name}");
}

class Person
{
    static int minAge = 0;
    string name;
    int age;
    public Person(string name, int age)
    {
        this.name = name;
        this.age = age;
    }
    public void Print() => Console.WriteLine($"{name} - {age}");
}

Чтобы получить и статические, и не статические, и публичные, и непубличные поля, в метод GetFields() передается набор флагов

BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static

Консольный вывод:

Поля:
private String name
private Int32 age
private static Int32 minAge

Получение и изменение значения поля

Для получения одного поля по имени применяется метод GetField(), в который передается имя поля:

var name = myType.GetField("name", BindingFlags.Instance | BindingFlags.NonPublic);

В качестве второго необязательного параметра передается набор флагов.

Причем рефлексия позволяет получать значения и изменять их даже у привтаных полей. Например, получим и изменим значение поля name:

using System.Reflection;

Type myType = typeof(Person);
Person tom = new Person("Tom", 37);

// получаем приватное поле name
var name = myType.GetField("name", BindingFlags.Instance | BindingFlags.NonPublic);

// получаем значение поля name
var value =name?.GetValue(tom);
Console.WriteLine(value);   // Tom

// изменяем значение поля name
name?.SetValue(tom, "Bob");
tom.Print();    // Bob - 37

class Person
{
    static int minAge = 1;
    string name;
    int age;
    public Person(string name, int age)
    {
        this.name = name;
        this.age = age;
    }
    public void Print() => Console.WriteLine($"{name} - {age}");
}

Свойства

Для извлечения всех свойств типа применяется соответственно метод GetProperties(), который возвращает массив объектов PropertyInfo. Для получения одного свойства по имени применяется метод GetProperty(), в который передается название свойства и который возвращает объект PropertyInfo?.

Некоторый основной функционал класса PropertyInfo:

  • Свойство Attributes: возвращает коллекцию атрибутов свойства

  • Свойство CanRead: возвращает true, если свойство доступно для чтения

  • Свойство CanWrite: возвращает true, если свойство доступно для записи

  • Свойство GetMethod: возвращает get-акссесор в виде объекта MethodInfo?

  • Свойство SetMethod: возвращает set-акссесор в виде объекта MethodInfo?

  • Свойство PropertyType: возвращает тип свойства

  • Метод GetValue(): возвращает значение свойства

  • Метод SetValue(): устанавливает значение свойства

Используем некоторые свойства PropertyInfo для получения информации о свойствах:

using System.Reflection;

Type myType = typeof(Person);
foreach (PropertyInfo prop in myType.GetProperties(
    BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static))
{
    Console.Write($"{prop.PropertyType} {prop.Name} {{");

    // если свойство доступно для чтения
    if (prop.CanRead) Console.Write("get;");
    // если свойство доступно для записи
    if (prop.CanWrite) Console.Write("set;");
    Console.WriteLine("}");
}

class Person
{
    public string Name { get; }
    public int Age { get; set; }
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
    public void Print() => Console.WriteLine($"{Name} - {Age}");
}
System.String Name {get;}
System.Int32 Age {get;set;}

С помощью методов PropertyInfo можно манипулировать значением свойства. Например, получим и изменим значение свойства:

using System.Reflection;

Type myType = typeof(Person);
Person tom = new Person("Tom", 37);
// получаем свойство Age
var ageProp = myType.GetProperty("Age");
// получаем значение свойства Age у объекта tom
var age = ageProp?.GetValue(tom);
Console.WriteLine(age); // 37
// устанавливаем новое значение для свойства Age объекта tom
ageProp?.SetValue(tom, 22);
tom.Print();    // Tom - 22

class Person
{
    public string Name { get; }
    public int Age { get; set; }
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
    public void Print() => Console.WriteLine($"{Name} - {Age}");
}

Для получения значения свойства в метод GetValue() объекта PropertyInfo передается объект, у которого вызывается свойства. Результатом метода является значение свойства. Для установки значения в метод SetValue() объекта PropertyInfo передается объект, у которого устанавливается свойство, и собственно новое значение свойства.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850