Monday, December 03, 2012

Новое в рефлексии для .NET 4.5

.NET 4.5 включает в себя некоторые изменения к System.Reflection. Самое значительно из них это то, что Type теперь разделён на два отдельных класса: Type и TypeInfo. Объект TypeInfo хранит в себе полное определение, а сам Type теперь хранит только общие данные. Если вы используете рефлексию из вашего десктопного или веб-приложения под NET 4.5, то старое API до сих пор тоже доступно наряду с новыми методами рефлексии. Сегодня я сфокусируюсь на том, как использовать некоторые из основных функций нового API.

Обзор Type и TypeInfo

Класс Type обеспечивает общее проредстваление о структуре объекта. TypeInfo же представляет полное определение объекта, включая его связи с родительским и наследованными классами. Более того, API класса Type было обновлено и теперь возвращает коллекции в виде типизированных IEnumerable, а не как раньше — массивов. В случае больших и сложных сборок это позволяет читать значения результатов рефлексии по одному, а также упрощает использование метаданных типов при помощи LINQ. Приложения Windows Store имеют доступ только к этим новым IEnumerable коллекциям.

Изменения API класса Type

Давайте посмотрим на некоторые метаданные, которые могут быть получены из Type без использования TypeInfo, а затем погрузимся в API TypeInfo. API класса Type позволяет получать общую информацию о типах. Это означает, что вы можете получить такие метаданные как имя, пространство имён, полное имя, модуль и так далее. Это осуществляется через то же самое API как и в .NET 4.0. Например, чтобы получить полное имя и пространство имён некоторого типа, вы можете сделать следующее:

Type stringType = typeof(string);
string fullName = stringType.FullName;
string stringNameSpace = stringType.Namespace;

API TypeInfo

Как вы видите, Type обеспечивает общее представление о структуре класса. Если вы хотите погрузиться немного глубже, то вы можете использовать новое API класса TypeInfo. Значение TypeInfo вы можете получить из Type вызовом его метода GetTypeInfo(). Возьмём, например, класс Person, который содержит в себе свойства имени (FirstName), фамилии (LastName), событие Modified и метод Save:

public class Person 
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public event EventHandler Modified;
    public void Save()
    {
        // сохраняем объект в репозиторий...
    }
}

Теперь допустим, что вам нужно узнать какие свойства, методы и события определены в классе Person. Это можно легко узнать из TypeInfo при помощи его свойств DeclaredProperties, DeclaredMethods и DeclaredProperties:

TypeInfo personInfo = personType.GetTypeInfo();
IEnumerable<PropertyInfo> declaredProperties = personInfo.DeclaredProperties;
IEnumerable<MethodInfo> declaredMethods = personInfo.DeclaredMethods;
IEnumerable<EventInfo> declaredEvents = personInfo.DeclaredEvents;

Другой общей задачей рефлексии является необходимость найти все типы внутри сборки. При помощи обновленного API System.Reflection, класс Assembly теперь возвращает коллекцию TypeInfo вместо массива Type. Например чтобы получить все типы определённые в выполняемой сборке, вы можете использовать свойство TypeInfo.Assembly, а затем прочитать свойство DefinedTypes на полученном объекте Assembly:

Assembly myAssembly = this.GetType().GetTypeInfo().Assembly;
IEnumerable<TypeInfo> myTypes = myAssembly.DefinedTypes;

Read more: Habrahabr
QR:  Inline image 1

Posted via email from Jasper-Net