Полное руководство по языку программирования С# 14 и платформе .NET 10 / Рефлексия

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

Начальный ⏱ 4 мин чтения 👁 2 🕓 обновлено 11.08.2026

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

Для извлечения всех полей применяется метод 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 передается объект, у которого устанавливается свойство, и собственно новое значение свойства.

Проверь себя

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

Практические задания

Лёгкое Ручная проверка Заполните пропуск в коде (1)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

using _____.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}");
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (2)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

BindingFlags._____ | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (3)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

Поля:
private String name
private Int32 _____
private static Int32 minAge
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (4)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

var _____ = myType.GetField("name", BindingFlags.Instance | BindingFlags.NonPublic);
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (5)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

using System.Reflection;

Type myType = _____(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}");
}
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (1)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

using System.Reflection;

Type myType = typeof(Person);

Console.WriteLine("Поля:");
foreach (FieldInfo _____ in myType.GetFields(
    _____.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}");
}
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (2)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

_____.Instance | BindingFlags._____ | BindingFlags.Public | BindingFlags.Static
Войдите, чтобы отправить решение
Среднее Ручная проверка Расставьте строки кода в правильном порядке
+20 XP

Строки кода из примера этого урока перемешаны. Впишите их в правильном порядке, каждую строку — с новой строки.

private Int32 age
private String name
Поля:
private static Int32 minAge
Войдите, чтобы отправить решение
Сложное Ручная проверка Объясните и модифицируйте пример из урока «Исследование полей и свойств с помощью рефлексии»
+30 XP

Опишите своими словами, что делает приведённый пример кода из урока «Исследование полей и свойств с помощью рефлексии», и предложите одно осмысленное изменение (например, другое входное значение или дополнительное условие). Приведите итоговый код.

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}");
}
Войдите, чтобы отправить решение
Сложное Ручная проверка Найдите потенциальную проблему в коде урока «Исследование полей и свойств с помощью рефлексии»
+30 XP

Изучите приведённый фрагмент кода и опишите, при каких входных данных или условиях он может сработать не так, как ожидается (граничный случай, отсутствие проверки и т.п.). Предложите исправленный вариант.

BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static
Войдите, чтобы отправить решение
Мини-проект Ручная проверка Мини-проект по теме «Исследование полей и свойств с помощью рефлексии»
+50 XP

Соберите небольшую программу, которая последовательно демонстрирует ключевые идеи урока. Программа должна быть рабочей и содержать минимум два самостоятельно написанных фрагмента, а не просто копию примера из урока.

Войдите, чтобы отправить решение
Домашнее задание Ручная проверка Домашнее задание по теме «Исследование полей и свойств с помощью рефлексии»
+25 XP

Напишите собственную небольшую программу, применяющую материал темы «Исследование полей и свойств с помощью рефлексии». Используйте не менее одной конструкции, показанной в примерах урока. Прикрепите код решения и краткое описание того, что он делает.

Войдите, чтобы отправить решение

Обсуждение (0)

Войдите, чтобы оставить комментарий.