为泛型方法传递具体类型参数时,返回泛型IEnumerable
本文关键字:返回 泛型 IEnumerable 类型参数 泛型方法 | 更新日期: 2023-09-27 18:23:43
此代码示例取自此答案https://stackoverflow.com/a/16491759/98706
public static Boolean PurgeDataObject(this IDataObject dataObject, Guid uid)
{
return PurgeDataObjectImpl((dynamic) dataObject, uid);
}
private static Boolean PurgeDataObjectImpl<T>(T dataObject, Guid uid)
where T : IDataObject
{
return DataProvider.DeleteDataObject<T>(uid, DataProvider.GetConnection());
}
我有一个类似的情况,我想在执行时返回基于类型的相关EF实体,以尝试清理一些现有的继承代码,如下所示:(
不同的是,我希望函数返回IEnumerable<T>
GetFilteredData
没有T
的概念,所以我得到了The type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?)
的编译错误
private IEnumerable<T> GetFilteredData(Type entityType, SortedList<string, string> filterList, List<int> weeks)
{
return GetFilteredDataImpl((dynamic)entityType, filterList, weeks);
}
private IEnumerable<T> GetFilteredDataImpl<T>(T entityType, SortedList<string, string> filterList, List<int> weeks) where T : EntityObject
{
var data = _modelContext.CreateObjectSet<T>().AsExpandable();
// do more filtering and then call .ToList() to return a List<T>
}
如果不使用反射,就无法将Type
类转换为通用T
参数。参数也需要作为方法的一部分出现。
Jon Skeet通过实例将类型推理与泛型相结合,以确保类型安全并简化泛型代码。不幸的是,使用Type
和反射将失去这种类型的安全性。
private IEnumerable<EntityObject> GetFilteredData(Type entityType,
SortedList<string, string> filterList,
List<int> weeks)
{
var method = typeof(<class>).GetMethod("GetFilteredDataImpl");
var generic = method.MakeGenericMethod(entityType);
return (IEnumerable<EntityObject>)generic.Invoke(this, new[] { filterList, weeks });
}
private IEnumerable<T> GetFilteredDataImpl<T>(SortedList<string, string> filterList,
List<int> weeks)
where T : EntityObject
{
var data = _modelContext.CreateObjectSet<T>().AsExpandable();
// do more filtering and then call .ToList() to return a List<T>
}
但是,您可以创建一个要传入的对象。
private IEnumerable<EntityObject> GetFilteredData(Type entityType, SortedList<string, string> filterList, List<int> weeks)
{
var instance = (EntityObject)Activator.CreateInstance(entityType);
return GetFilteredDataImpl((dynamic)instance, filterList, weeks);
}
private IEnumerable<T> GetFilteredDataImpl<T>(T entityType, SortedList<string, string> filterList, List<int> weeks) where T : EntityObject
{
var data = _modelContext.CreateObjectSet<T>().AsExpandable();
// do more filtering and then call .ToList() to return a List<T>
}
这仍然会返回一个IEnumerable<EntityObject>
,但它会生成垃圾,并且您正在用ArgumentException
换取InvalidCastException
。