Построение делегата C # для вызова получателя унаследованного свойства - PullRequest
0 голосов
/ 06 октября 2019

Я создаю универсальный, многократно используемый код отражения C # в .NET Core 2 с целью хранения делегатов для повторного использования, чтобы избежать большинства затрат на отражение. Первый вариант использования этого кода - получить значения свойств. Мой основной вопрос как создать делегат для вызова открытых свойств унаследованного типа .

У меня есть класс, который, по сути, служит оберткой / адаптером отражения для целевого класса, используяПараметр универсального типа T в качестве важного параметра для Delegate.CreateDelegate выглядит следующим образом:

        someDelegateStoredForReuse = (Func<T, object>)Delegate.CreateDelegate(typeof(Func<T, object>), null, PropertyInfo.GetGetMethod());

Структура кода, обертка / адаптер фактически хранит и повторно использует обертки вокруг каждого метода получения свойства, где указанная выше строка кодапоявляется. Когда создается экземпляр класса-оболочки, он зацикливается на объектах PropertyInfo, возвращаемых typeof (T) .GetProperties (), и для каждого из них создает оболочку свойства.

Это все работает для открытых свойств самого класса, но не для унаследованных. В GetProperties () не передается комбинация флагов привязки, включая BindingFlags.FlattenHierarchy в сочетании с Public |NonPublic возвращает унаследованные свойства, которые будут работать для этой цели.

Чтобы получить унаследованные свойства, я переключился на получение их из базового типа типа и прохождение строки предка. Тем не менее, я не могу заставить Delegate.CreateDelegate работать с этим подходом, потому что я не могу получить аргумент универсального типа предка из его System.Type. Вызов Delegate.CreateDelegate для создания Func с унаследованным свойством .GetGetMethod () не работает, поскольку T не является типом parent / ancestor (он вызывает исключение при вызове делегата).

Моя проблема будет решена одним из следующих решений, ни одно из которых мне не удалось найти с помощью .NET Core 2, по крайней мере:

  1. Вызовите Delegate.CreateDelegate длясоздайте рабочий делегат для вызова MethodInfo метода получения отраженного свойства, используя тип, не переданный в качестве универсального параметра, т. е. используя System.Type

  2. Получите объекты PropertyInfo для унаследованных свойств вначальный вызов .GetProperties (), если возвращенный PropertyInfos .GetGetMethod () вернул бы MethodInfo, позволяющий создать рабочий делегат, используя переданный универсальный тип T наследующего типа

Мои извинениядля многословности, но я хотел быть точным. Спасибо за понимание.

1 Ответ

0 голосов
/ 06 октября 2019

Вы можете использовать Expression.GetFuncType для генерации Func<> с общими параметрами, которые вы хотите.

var delegateType = Expression.GetFuncType(property.DeclaringType, property.PropertyType);
var getter = property.GetMethod.CreateDelegate(delegateType);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...