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