我有一个看起来像这样的方法:
private IEnumerable<T> QueryCollection<T>() where T : BaseObj
{
IEnumerable<T> items = query<T>();
return items;
}
我现在有一种情况,如果“T”支持某个接口(interface)(它可能不支持,所以我不能简单地将它添加为 T 的约束),我想过滤这个项目集合。所以我想要这样的东西:
private IEnumerable<T> QueryCollection<T>() where T : BaseObj
{
IEnumerable<T> items = query<T>();
if (typeOf(T).GetInterface(ITeamFilterable) != null)
{
items = FilterByTeams(items);
}
return items;
}
检查我的通用类型是否支持某个接口(interface)的推荐方法是什么**然后如果是,则
- 在方法中使用它来过滤集合
- 但在整体方法中仍然返回类型为“T”的集合
注意:FilterByTeams 接受:
IEnumerable<ITeamFilterable>
并返回
IEnumerable<ITeamFilterable>
我是否需要转换集合 2 次(一次转换为接口(interface)的 List,然后再次转换回 T 的列表?)
恐怕你不能使用is
/as
在这种情况下,除非您可以开始枚举查询。
你可以像这样使用反射:
private IEnumerable<T> QueryCollection<T>() where T : BaseObj
{
IEnumerable<T> items = query<T>();
if (typeof(ITeamFilterable).IsAssignableFrom(typeof(T)))
items = (IEnumerable<T>)(object)FilterByTeams(items.Cast<ITeamFilterable>());
return items;
}
但是如果您可以枚举查询,则可以这样做以避免反射(假设您没有 null
项):
private IEnumerable<T> QueryCollection<T>() where T : BaseObj
{
IEnumerable<T> items = query<T>();
ICollection<T> itemsCollection = items as ICollection<T> ?? items.ToList();
if (itemsCollection.Count > 0)
{
var firstItem = itemsCollection.First();
if (firstItem is ITeamFilterable)
return (IEnumerable<T>)(object)FilterByTeams(itemsCollection.Cast<ITeamFilterable>());
}
return itemsCollection;
}
自 ITeamFilterable
起,类型转换将开始工作是 T
和 IEnumerable<T>
是协变的,但你必须转换为 object
介于两者之间以满足泛型约束。使用这些转换,无需到处复制项目。