Ваше приведение неверно.
Вы не можете привести к (DbSet<T>)
, потому что это не конкретный тип, если T
не определен внутри универсального метода или универсального типа.
ВыУ меня есть пара возможностей.
Если у DbSet есть базовый класс (например, DbSet_BaseClass
в моем коде ниже), из которого вы все еще можете реализовать свой метод Clear()
- измените его сигнатуру с:
public static void Clear<T>(this DbSet<T>)
на:
public static void Clear(this DbSet_BaseClass)
Затем вы можете изменить свой актерский состав в .ForEach
на ((DbSet_BaseClass)pi.GetValue...
Если вы не можете этого сделать, вы можете отразить-вызватьметод расширения Clear
путем создания его конкретной универсальной версии для T
DbSet<T>
:
MethodInfo myClearMethod = typeof(container_type).GetMethod(
"Clear", BindingFlags.Public | BindingFlags.Static);
Затем, учитывая информацию о свойстве и экземпляр контекста:
Type propType = pi.PropertyType;
Type typeofT = propType.GetGenericArguments[0];
MethodInfo toInvoke = myClearMethod.MakeGenericMethod(typeofT);
//now invoke it
toInvoke.Invoke(null, new[] { pi.GetValue(currentContext, null) });
Существует множество оптимизаций, которые можно поставить поверх этого, кэширование делегатов и т. Д., Но это будет работать.
Обновление
Или см. Ответ @Daniel Hilgarth для классный способ динамической отправки вызова к методу расширения без необходимости делать какие-либо извыше (динамическая диспетчеризация делает что-то подобное, но для вас все кэшируется сверху).Если бы это был я - я бы использовал это.