Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> Язык C

Рефлексия в C#: Runtime Type Discovery и динамическое программирование

Что такое рефлексия

Рефлексия (Reflection) — механизм получения информации о типах, членах, атрибутах и сборках во время выполнения. Позволяет: инспектировать метаданные, создавать экземпляры, вызывать методы, читать/писать поля/свойства динамически. Классы в System.Reflection.

Основные сценарии использования

Ключевые классы

КлассНазначение
TypeЦентральный класс — представляет тип (class, struct, interface, enum, delegate). Получение: typeof(MyClass), obj.GetType(), Type.GetType("FullName")
AssemblyСборка (.dll/.exe). Assembly.GetExecutingAssembly(), Assembly.LoadFrom(path)
MemberInfoБазовый для FieldInfo, PropertyInfo, MethodInfo, ConstructorInfo, EventInfo
ParameterInfoИнформация о параметре метода
CustomAttributeDataДанные атрибута без создания экземпляра атрибута

Получение Type

// 1. typeof — compile-time тип
Type t1 = typeof(string);

// 2. GetType() — runtime тип объекта
object obj = "hello";
Type t2 = obj.GetType(); // System.String

// 3. По строке имени (сборка-полное имя)
Type t3 = Type.GetType("System.Int32, mscorlib"); // или без сборки для текущей
Type t4 = Assembly.GetExecutingAssembly().GetType("MyNamespace.MyClass");

Инспекция членов типа

Type t = typeof(MyClass);

// Публичные члены экземпляра
var methods = t.GetMethods(BindingFlags.Public | BindingFlags.Instance);
var properties = t.GetProperties();
var fields = t.GetFields();
var constructors = t.GetConstructors();

// Все члены (включая непубличные)
var allMethods = t.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | 
                              BindingFlags.Instance | BindingFlags.Static);

Создание экземпляров (Activator)

// Через parameterless конструктор
object obj = Activator.CreateInstance(typeof(MyClass));

// Через конструктор с параметрами
object obj2 = Activator.CreateInstance(typeof(MyClass), args: new object[] { "param1", 42 });

// Generic версия (C# 2.0+)
MyClass instance = Activator.CreateInstance();

Вызов методов и доступ к свойствам/полям

Type t = typeof(MyClass);
object instance = Activator.CreateInstance(t);

// Вызов метода
MethodInfo method = t.GetMethod("MyMethod");
object result = method.Invoke(instance, new object[] { arg1, arg2 });

// Чтение/запись свойства
PropertyInfo prop = t.GetProperty("MyProperty");
prop.SetValue(instance, "new value");
object val = prop.GetValue(instance);

// Чтение/запись поля
FieldInfo field = t.GetField("myField");
field.SetValue(instance, 123);

Чтение атрибутов

[MyAttribute("value", Param = 42)]
public class MyClass { }

var attrs = typeof(MyClass).GetCustomAttributes(inherit: false);
foreach (var attr in attrs)
    Console.WriteLine($"{attr.ConstructorArg}, {attr.Param}");

Пример из оригинала: чтение DebugInfo атрибутов

Type type = typeof(Rectangle);

// Атрибуты класса
foreach (object attrObj in type.GetCustomAttributes(false))
{
    if (attrObj is DebugInfo dbi)
    {
        Console.WriteLine($"Bug: {dbi.BugNo}, Dev: {dbi.Developer}, Review: {dbi.LastReview}, Msg: {dbi.Message}");
    }
}

// Атрибуты методов
foreach (MethodInfo m in type.GetMethods())
{
    foreach (Attribute attr in m.GetCustomAttributes(true))
    {
        if (attr is DebugInfo dbi)
        {
            Console.WriteLine($"Method {m.Name}: Bug {dbi.BugNo}, Msg: {dbi.Message}");
        }
    }
}

Performance: кэширование и исходные генераторы

Безопасность

Рефлексия может обходить проверки доступа (BindingFlags.NonPublic). В .NET Core / .NET 5+ по умолчанию ограничена (требует ReflectionPermission в полной доверительной среде). Используйте осторожно.

Язык C

  1. C# Hello World — создание вашего первого C# приложения
  2. Понимание ключевых слов и идентификаторов C#: правила, списки и лучшие практики
  3. Мастерство C# переменных и примитивных типов данных: полное руководство
  4. Операторы C# — исчерпывающее руководство по операторам в C#
  5. Освоение побитовых и сдвиговых операторов в C#: полное руководство
  6. Основы ввода-вывода в C#: Console.WriteLine, ReadLine и форматирование
  7. Выражения, операторы и блоки в C#: подробное руководство с примерами
  8. Освоение комментариев в C#: виды, лучшие практики и XML-документация
  9. Оператор break в C#: как и когда использовать
  10. Оператор continue в C#: как эффективно пропускать итерации циклов