1.19M
Category: programmingprogramming

Рефлексия C#

1.

Рефлексия
процесс выявления типов (объектов типа Type) во время
выполнения приложения.
Любое наше приложение C# состоит из объектов,
реализующих те или иные классы и интерфейсы, а также
из методов, свойств объектов и других элементов.
Рефлексия же (отражение) позволяет определить все эти
элементы приложения прямо во время выполнения
приложение и, в случае необходимости, производить
манипуляции с выявленными объектами

2.

Когда удобно использовать
рефлексию
• При необходимости доступа к атрибутам в
метаданных программы.
• Для проверки и создания экземпляров
типов в сборке.
• Для создания типов во время выполнения.
• Для выполнения позднего связывания,
которое обеспечивает доступ к методам в
типах, созданных во время выполнения.

3.

Основные классы
• Основные методы и классы рефлексии
сосредоточены в пространстве
имен System.Reflection

4.

• Assembly — класс, представляющий сборку и позволяющий
манипулировать этой сборкой
• AssemblyName — класс, хранящий информацию о сборке
• MemberInfo — базовый абстрактный класс, определяющий
общий функционал для
классов EventInfo, FieldInfo, MethodInfo и PropertyInfo
• EventInfo — класс, хранящий информацию о событии
• FieldInfo — хранит информацию об определенном поле типа
• MethodInfo — хранит информацию об определенном методе
• PropertyInfo — хранит информацию о свойстве
• ConstructorInfo — класс, представляющий конструктор
• Module — класс, позволяющий получить доступ к
определенному модулю внутри сборки
• ParameterInfo — класс, хранящий информацию о параметре
метода

5.

Пример: получение информации о версии
сборки в C# (класс AssemblyName)
Довольно часто в приложении необходимо
выводить информацию о его версии,
например, это может потребоваться при
оформлении окна «About» вашего
приложения. Для этого мы можем завести
какую-либо константу, а можем использовать
возможности, предоставляемые
классом AssemblyName

6.

7.

8.

Класс System.Type
• Чтобы получить информацию о членах
типа, нам необходимо использовать
класс System.Type. Этот класс представляет
изучаемый тип, инкапсулируя всю
информацию о нем. С помощью свойств и
методов System.Type можно получить
различную информацию об изучаемом
классе

9.


Метод GetConstructors() возвращает все конструкторы данного типа в виде
набора объектов ConstructorInfo
Метод GetEvents() возвращает все события данного типа в виде массива
объектов EventInfo
Метод GetFields() возвращает все поля данного типа в виде массива
объектов FieldInfo
Метод GetInterfaces() получает все реализуемые данным типом интерфейсы в
виде массива объектов Type
Метод GetMembers() возвращает все члены типа в виде массива
объектов MemberInfo
Метод GetMethods() получает все методы типа в виде массива
объектов MethodInfo
Метод GetProperties() получает все свойства в виде массива
объектов PropertyInfo
Свойство Name возвращает имя типа
Свойство Assembly возвращает название сборки, где определен тип
Свойство Namespace возвращает название пространства имен, где определен
тип
Свойство IsArray возвращает true, если тип является массивом
Свойство IsClass возвращает true, если тип представляет класс
Свойство IsEnum возвращает true, если тип является перечислением
Свойство IsInterface возвращает true, если тип представляет интерфейс

10.

Получение типа
Чтобы управлять типом во время выполнения
приложения и получать всю информацию о
нем, необходимо этот тип каким-либо
способом получить. В C# это можно сделать
тремя способами:
• с помощью ключевого слова typeof,
• с помощью метода GetType() класса Object
• применяя статический метод Type.GetType()

11.

Получение типа через typeof
Определим в нашем приложении любой класс, например,
вот такой:

12.

воспользуемся ключевым
словом typeof чтобы получить тип:

13.

Получение типа с помощью
метода GetType класса Object

14.

Использование статического
метода Type.GetType()
первый параметр указывает на полное имя класса, включая и
пространство имен, в котором этот класс находится.
• второй параметр указывает, будет ли
генерироваться исключение, если класс не удастся найти. В
данном случае значение true означает, что исключение будет
генерироваться.
• третий параметр указывает, надо ли учитывать регистр
символов в первом параметре. Значение true означает, что
регистр игнорируется

15.

Получение и изучение членов класса
Для начала попробуем вывести всю информацию о типе,
воспользовавшись методом GetMembers():
Свойство DeclaringType возвращает полное название типа.
Свойство MemberType возвращает значение из
перечисления MemberTypes, в котором определены следующие
типы:
• MemberTypes.Constructor — член класса представляет собой
конструктор
• MemberTypes.Method — член класса представляет собой метод
• MemberTypes.Field — член класса представляет собой поле
• MemberTypes.Event — член класса представляет собой событие
• MemberTypes.Property — член класса представляет собой
свойство
• MemberTypes.NestedType — член класса представляет собой
вложенный тип

16.

Получение и изучение членов класса

17.

Получение информации о методах

18.

Замечание
Можно воспользоваться переопределенной версией
методы GetMethods(), которая выглядит следующим образом:
MethodInfo[] GetMethods(BindingFlags)
Перечисление BindingFlags может принимать следующие значения:
• DeclaredOnly— получает только методы непосредственно данного
класса, унаследованные методы не извлекаются
• Instance— получает только методы экземпляра
• NonPublic— извлекает не публичные методы
• Public— получает только публичные методы
• Static— получает только статические методы
MethodInfo[] methods = type.GetMethods(BindingFlags.DeclaredOnly |
BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

19.

Получение конструкторов
применяется метод ConstructorInfo[] GetConstructors()

20.

Получение информации о полях и
свойствах
применяются соответственно
методы GetFields() и GetProperties():

21.

Работа со свойствами объекта (класс
PropertyInfo)
Класс для
издевательств:

22.

Как найти определенное свойство
класса в C#
• обратить внимание на выставленные флаги BindingFlags.
Используя связку BindingFlags.IgnoreCase |
BindingFlags.Instance| BindingFlags.Public

23.

Если свойство обнаружено, то, используя методы и
свойства класса PropertyInfo мы можем его
детально исследовать:

24.

Как получить значение свойства
объекта в C#
Для этого воспользуемся методом GetValue() у PropertyInfo

25.

Замечание
в реальном проекте мы можем столкнуться с ситуацией, когда свойство
какого-либо класса само является классом, а этот класс содержит в себе
свойство, которое также является классом и т.д., то есть вложенность
объектов в исследуемом экземпляре может быть самая разная.

26.

Как записать значение свойства
объекта в C#

27.

Атрибуты
• Атрибуты в .NET представляют специальные
инструменты, которые позволяют встраивать в
сборку дополнительные метаданные.
• Атрибуты могут применяться как ко всему
типу (классу, интерфейсу и т.д.), так и к
отдельным его частям (методу, свойству и т.д.).
• Основу атрибутов составляет класс
System.Attribute, от которого образованы все
остальные классы атрибутов.

28.

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

29.

применим его к некоторому классу:

30.

31.

Примеры использования рефлексии

32.

Динамическое создание объекта по
строке
Иногда бывает
удобно создавать
объекты, зная
лишь строку с
названием типа.
Например,
представьте, что
у вас есть строка,
содержащая имя
класса, и вы
хотите создать
экземпляр этого
класса.

33.

Чтение значения приватного
поля
Иногда возникает ситуация, когда нужно получить
значение приватного поля объекта. Рефлексия позволяет
это сделать.

34.

Вызов приватного метода
Точно так же, как и с полем, можно вызвать приватный метод
объекта.

35.

Динамическое изменение значения
свойства
Иногда нужно изменить значение свойства объекта, не зная точно его
названия.

36.

Работа с атрибутами
Часто приходится работать с атрибутами, чтобы добавить
дополнительную информацию к классам, методам или
свойствам. Рефлексия позволяет считывать эту
информацию.

37.

Динамическое создание экземпляра класса по
имени
Иногда нужно создать экземпляр класса, зная только его имя в виде строки. Это может
пригодиться, например, при работе с конфигурационными файлами или настройками.

38.

Получение списка всех методов
класса
Бывает полезно узнать, какие методы доступны в
конкретном классе. Рефлексия позволяет легко получить
такую информацию.

39.

Получение значения статического
поля
Статические поля принадлежат классу, а не конкретному
экземпляру. Рефлексия позволяет получить значение статического
поля.

40.

Динамическое выполнение
метода
Иногда нужно вызвать метод, не зная его точного имени на
этапе компиляции. Это может понадобиться, например, при
создании универсальных обработчиков событий.

41.

Определение базовых классов и
интерфейсов
Иногда нужно узнать, от каких классов наследуется конкретный
класс или какие интерфейсы он реализует. Рефлексия поможет в
этом.
English     Русский Rules