Рефлексия. Примеры получения информации о методах, интерфейсах, классах, структурах, перечислениях, делегатах, полях типов, параметрах методов, статистических данных о типах
Содержание
- 1. Что собой представляет метод System.Type.GetType()?
- 2. Что такое рефлексия методов? Как получить информацию о методах? Пример рефлексии методов
- 3. Как получить информацию о полях класса, структуры или перечисления? Примеры рефлексии полей и свойств
- 4. Как получить информацию об интерфейсах, которые реализует класс? Пример рефлексии интерфейсов
- 5. Пример использования рефлексии для получения дополнительных сведений о типе (классе, структуре, перечислении)
- 6. Как получить информацию о свойствах (properties) класса? Пример
- 7. Пример использования рефлексии для получения информации о параметрах метода
- Связанные темы
Поиск на других ресурсах:
1. Что собой представляет метод System.Type.GetType()?
Метод System.Type.GetType() предназначен для получения экземпляра типа, который задан параметром. Параметр метода есть тип string. Параметр указывает название типа, для которого нужно получить информацию. В общем случае, метод System.Type.GetType() имеет 7 перегруженных реализаций.
Чтобы получить перечень методов некоторого типа (например, класса) нужно сначала получить объект, содержащий информацию о типе. Это делается с помощью метода
GetType("NameSpace.TypeName")
где
- NameSpace – название пространства имен, в котором размещается тип с именем TypeName, требующий исследования;
- TypeName – название типа, о котором нужно получить информацию. Типом может быть класс, структура, интерфейс, перечисление, делегат.
Например
Type tp = Type.GetType("Dates.Date");
В этом примере нужно создается экземпляр (объект) с именем tp, содержащий информацию о типе с именем Date, который объявлен в пространстве имен Dates.
⇑
2. Что такое рефлексия методов? Как получить информацию о методах? Пример рефлексии методов
Рефлексия методов позволяет получить информацию о перечне общедоступных (public) методов из заданного типа. Информацию о методах можно получать для класса, структуры или интерфейса. Только эти типы могут содержать объявления методов.
Чтобы получить перечень методов заданного экземпляра типа, нужно вызвать метод GetMethods(), возвращающий массив типа MethodInfo, который содержит всю необходимую информацию о методах.
Пример. Задан класс Date, который описывает дату. В классе реализованы 3 внутренние переменные и 6 методов доступа к ним. Ниже приведен текст программы, которая демонстрирует рефлексию методов. Программа создана по шаблону Console Application.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; // подключить пространство имен System.Reflection using System.Reflection; namespace ConsoleApp2 { // класс, который описывает дату public class Date { int number; int month; int year; // public int GetNumber() { return number; } public int GetMonth() { return month; } public int GetYear() { return year; } public void SetNumber(int nnumber) { number = nnumber; } public void SetMonth(int nmonth) { month = nmonth; } public void SetYear(int nyear) { year = nyear; } } class Program { static void Main(string[] args) { // получить информацию о методах // получить экземпляр типа по его имени Type tp = Type.GetType("ConsoleApp2.Date"); // название класса - "Date" в сборке ConsoleApp2 // получить массив методов класса Date MethodInfo[] methods = tp.GetMethods(); // вывести названия методов на экран int i = 0; foreach (MethodInfo mi in methods) { i++; Console.WriteLine("Method[{0}] = {1}", i, mi.Name); } } } }
В результате выполнения данного кода, на экран будет выведен перечень названий методов, которые доступны для любого объекта класса Date:
Method[1] = GetNumber Method[2] = GetMonth Method[3] = GetYear Method[4] = SetNumber Method[5] = SetMonth Method[6] = SetYear Method[7] = ToString Method[8] = Equals Method[9] = GetHashCode Method[10] = GetType Press any key to continue . . .
Следует отметить следующее:
- информацию можно получить только о тех методах, которые объявленны как общедоступные с модификатором доступа public;
- чтобы получить экземпляр типа методом GetType() из статической функции Main(), обязательно нужно перед именем класса указывать название пространства имен в котором этот класс реализован.
⇑
3. Как получить информацию о полях класса, структуры или перечисления? Примеры рефлексии полей и свойств
Чтобы получить информацию о поле (свойстве) некоторого типа (класс, структура, перечисление), нужно использовать метод Type.GetFields(). Этот метод возвращает массив типа FieldInfo. Тип FieldInfo содержит всю необходимую информацию о полях и свойствах, которые объявлены как public.
Пример 1. Получение информации о полях структуры. Задана структура Worker. В структуре реализованы 3 поля с именами name, age, rank. В примере демонстрируется вывод информации о названии поля и его типе (свойство FieldType). Пример реализован как консольное приложение
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; // подключить System.Reflection using System.Reflection; namespace TrainReflection { // структура, которая реализует информацию о работнике public struct Worker { public static string name; // имя работника public int age; // век работника public float rank; // рейтинг работника } class Program { static void Main(string[] args) { // получить информацию о полях структуры Worker // создать объект, который содержит информацию о структуре Worker Type tp = Type.GetType("TrainReflection.Worker"); // получить информацию о полях структуры Worker FieldInfo[] fields = tp.GetFields(); // вывести названия полей, их типы и некоторые атрибуты int i = 0; string nameType; foreach (var field in fields) { i++; nameType = field.FieldType.ToString(); // получить название типа поля field структуры Worker Console.Write("Field[{0}] = {1}, type = {2}", i, field.Name, nameType); // проверка, статическое ли это поле if (field.IsStatic) Console.Write(", static"); // проверка, объявлено ли поле как public if (field.IsPublic) Console.Write(", public"); Console.WriteLine(); } } } }
В результате, на экран будет выведен следующий текст:
Field[1] = age, type = System.Int32, public Field[2] = rank, type = System.Single, public Field[3] = name, type = System.String, static, public Press any key to continue . . .
Таким же образом можно получить информацию о полях любого класса любой сборки. Достаточно знать только имя класса в сборке.
Пример 2. Получение информации о полях перечисления. Задано перечисление Month, реализующее сокращенные названия месяцев года. Ниже приведен пример получения информации о перечислении на основе информации о его имени.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; // подключить System.Reflection using System.Reflection; namespace TrainReflection { // перечисление, реализующее информацию о месяце года enum Month { Jan = 1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec } class Program { static void Main(string[] args) { // получить информацию о полях перечисления Month // создать объект, который содержит информацию о структуре Worker Type tp = Type.GetType("TrainReflection.Month"); // получить информацию о полях перечисления Month FieldInfo[] fields = tp.GetFields(); // вывести названия полей перечисления enum int i = 0; string value; foreach (var field in fields) { i++; Console.WriteLine("Field[{0}] = {1}", i, field.Name); } } } }
В результате, на экран будет выведен следующий текст
Field[1] = value__ Field[2] = Jan Field[3] = Feb Field[4] = Mar Field[5] = Apr Field[6] = May Field[7] = Jun Field[8] = Jul Field[9] = Aug Field[10] = Sep Field[11] = Oct Field[12] = Nov Field[13] = Dec Press any key to continue . . .
⇑
4. Как получить информацию об интерфейсах, которые реализует класс? Пример рефлексии интерфейсов
Чтобы получить перечень имен интерфейсов, которые поддерживаются заданным типом, используется метод GetInterfaces(). Этот метод возвращает массив интерфейсов типа Type[].
Название интерфейса помещается в свойстве Name.
Пример. Пусть задан интерфейс IDate, в котором объявляются имена двух методов: GetNumber(), SetNumber(). Также объявляется класс Date, реализующий дату. Класс Date наследует интерфейс IDate. В примере продемонстрировано:
- получение списка интерфейсов класса Date;
- получение списка методов интерфейса IDate.
Полный листинг программы, которая демонстрирует данный пример
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; // подключить System.Reflection using System.Reflection; namespace TrainReflection { // интерфейс с двумя объявленными методами interface IDate { int GetNumber(); void SetNumber(int nnumber); } // класс, который описывает дату - наследует интерфейс IDate public class Date:IDate { int number; int month; int year; // public int GetNumber() { return number; } public int GetMonth() { return month; } public int GetYear() { return year; } public void SetNumber(int nnumber) { number = nnumber; } public void SetMonth(int nmonth) { month = nmonth; } public void SetYear(int nyear) { year = nyear; } } class Program { static void Main(string[] args) { // получить информацию о методах // получить экземпляр типа по его имени Type tp = Type.GetType("TrainReflection.Date"); // название класса - "Date" // получить массив интерфейсов класса Date Type[] interfaces = tp.GetInterfaces(); // вывести названия интерфейсов класса Date на экран int i = 0; foreach (Type t in interfaces) { i++; Console.WriteLine("Interface[{0}] = {1}", i, t.Name); } Console.WriteLine(); // создать объект, который содержит информацию об интерфейсе IDate Type tpi = Type.GetType("TrainReflection.IDate"); // получить массив методов для интерфейса IDate с помощью объекта tpi MethodInfo[] methods = tpi.GetMethods(); // вывести перечень методов интерфейса IDate i = 0; foreach (MethodInfo mt in methods) { i++; // вывести полное имя каждого метода интерфейса Console.WriteLine("Method[{0}] = {1}", i, mt.Name); } } } }
В результате выполнения программы на экран будет выведено:
Interface[1] = IDate Method[1] = GetNumber Method[2] = SetNumber Press any key to continue . . .
⇑
5. Пример использования рефлексии для получения дополнительных сведений о типе (классе, структуре, перечислении)
С помощью рефлексии можно получать дополнительные сведения о типе. Типом может быть класс, структура, интерфейс, перечисление, делегат.
Пример. Пусть заданы два класса:
- класс Point, который реализует точку на координатной плоскости;
- класс Pixel, который реализует точку заданного цвета. Класс Pixel унаследован от класса Point.
Ниже приводится полный текст программы, которая выводит дополнительные сведения о классах Point и Pixel. Программа реализована как приложение типа Console Application.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; // подключить System.Reflection using System.Reflection; namespace TrainReflection { public class Point { // внутренние переменные класса protected int x; protected int y; // методы доступа public void GetXY(out int xx, out int yy) { xx = x; yy = y; } public void SetXY(int xx, int yy) { x = xx; y = yy; } } // класс Pixel есть производным от класса Point sealed class Pixel:Point { // внутренняя переменная color int color; // методы доступа public void GetXYC(out int xx, out int yy, out int cl) { GetXY(out xx, out yy); cl = color; } public void SetXYC(int xx, int yy, int cl) { SetXY(xx, yy); color = cl; } } class Program { static void Main(string[] args) { // создать объекты для классов Point и Pixel Type tPoint = Type.GetType("TrainReflection.Point"); Type tPixel = Type.GetType("TrainReflection.Pixel"); // вывести некоторую информацию о классе Point Console.WriteLine("Information about Point class:"); if (tPoint.IsAbstract) Console.WriteLine("Abstract class"); // абстрактный класс if (tPoint.IsArray) Console.WriteLine("Array"); // это есть массив if (tPoint.IsClass) Console.WriteLine("Class or delegate"); // это есть класс или делегат if (tPoint.IsEnum) Console.WriteLine("Enumeration"); // это есть перечисление if (tPoint.IsInterface) Console.WriteLine("Interface"); // это есть интерфейс if (tPoint.IsPublic) Console.WriteLine("Public"); // объявлен как public if (tPoint.IsSealed) Console.WriteLine("Sealed"); // запечатан Console.WriteLine(); // вывести некоторую информацию о классе Pixel Console.WriteLine("Information about Pixel class:"); if (tPixel.IsAbstract) Console.WriteLine("Abstract class"); // абстрактный класс if (tPixel.IsArray) Console.WriteLine("Array"); // это есть массив if (tPixel.IsClass) Console.WriteLine("Class or delegate"); // это есть класс или делегат if (tPixel.IsEnum) Console.WriteLine("Enumeration"); // это есть перечисление if (tPixel.IsInterface) Console.WriteLine("Interface"); // это есть интерфейс if (tPixel.IsPublic) Console.WriteLine("Public"); // объявлен как public if (tPixel.IsSealed) Console.WriteLine("Sealed"); // запечатан } } }
В результате выполнения программы, на экран будет выведено следующее:
Information about Point class: Class or delegate Public Information about Pixel class: Class or delegate Sealed Press any key to continue . . .
⇑
6. Как получить информацию о свойствах (properties) класса? Пример
Чтобы получить информацию о свойствах класса нужно вызвать метод GetProperties(). Этот метод возвращает массив типа PropertyInfo[]. Массив PropertyInfo[] содержит сведения о свойствах (properties) класса.
Пример. Продемонстрировано получение перечня свойств для класса Student из пространства имен TrainReflection. Свойства обязательно должны быть объявлены с модификатором доступа public.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; // подключить System.Reflection using System.Reflection; namespace TrainReflection { // информация о студенте class Student { string name; // имя студента string numBook; // номер зачетной книжки float rank; // рейтинг студента // свойства public string Name { get { return name; } set { name = value; } } public string NumBook { get { return numBook; } set { numBook = value; } } public float Rank { get { return rank; } set { rank = value; } } } class Program { static void Main(string[] args) { // получить информацию о свойствах из класса Student // получить объект типа System.Type Type tp = Type.GetType("TrainReflection.Student"); // получить перечень свойств PropertyInfo[] properties = tp.GetProperties(); // вывести перечень свойств int i = 0; foreach (PropertyInfo p in properties) { i++; Console.WriteLine("Property[{0}] = {1}", i, p.Name); } } } }
На экран будет выведен следующий текст
Property[1] = Name Property[2] = NumBook Property[3] = Rank Press any key to continue . . .
⇑
7. Пример использования рефлексии для получения информации о параметрах метода
Для конкретного метода можно получить информацию о его параметрах.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; // подключить System.Reflection using System.Reflection; namespace TrainReflection { // класс, который содержит математические функции class MathFunctions { // метод, который решает квадратное уравнение public bool CalcEquation(double a, double b, double c, out double x1, out double x2) { double d = b * b - 4 * a * c; if (a==0) { if (b==0) { x1 = x2 = 0; return false; } else { x1 = x2 = -c / b; return true; } } if (d<0) { x1 = x2 = 0; return false; } x1 = (-b - Math.Sqrt(d)) / (2 * a); x2 = (-b + Math.Sqrt(d)) / (2 * a); return true; } } class Program { static void Main(string[] args) { // получить информацию о свойствах из класса Student // получить объект типа System.Type Type tp = Type.GetType("TrainReflection.MathFunctions"); // получить объект, который содержит информацию о конкретном методе CalcEquation класса MathFunctions MethodInfo method = tp.GetMethod("CalcEquation"); // получить параметры метода CalcEquation ParameterInfo[] parameters = method.GetParameters(); // вывести параметры метода Console.WriteLine("Parameters of method CalcEquation:"); int i = 0; foreach (ParameterInfo p in parameters) { i++; Console.WriteLine("Parameter[{0}] = {1} of type {2}", i, p.Name, p.ParameterType.Name); } // вывести тип значения, которое возвращается методом string returnType = method.ReturnType.FullName; Console.WriteLine(); Console.WriteLine("The returned type: {0}", returnType); } } }
Вывод на экран будет следующим
Parameters of method CalcEquation: Parameter[1] = a of type Double Parameter[2] = b of type Double Parameter[3] = c of type Double Parameter[4] = x1 of type Double& Parameter[5] = x2 of type Double& The returned type: System.Boolean Press any key to continue . . .
⇑
Связанные темы
- Динамическая идентификация типов. Операторы is, as. Примеры
- Рефлексия типов. Получение метаданных типа. Пространство имен System.Reflection. Класс System.Type. Способы получения информации о типе
- Динамически загружаемые сборки. Класс Assembly. методы Load() и LoadFrom()