如何判断我的泛型类型是不是支持某个接口并为函数来回转换到该接口? [复制]
Posted
技术标签:
【中文标题】如何判断我的泛型类型是不是支持某个接口并为函数来回转换到该接口? [复制]【英文标题】:How can I tell if my generic type supports a certain interface and convert back and forthto that interface for a function? [duplicate]如何判断我的泛型类型是否支持某个接口并为函数来回转换到该接口? [复制] 【发布时间】:2014-11-22 22:52:00 【问题描述】:我有一个看起来像这样的方法:
private IEnumerable<T> QueryCollection<T>() where T : BaseObj
IEnumerable<T> items = query<T>();
return items;
我现在有一种情况,我想过滤这个项目集合,如果“T”支持某个接口(它可能不支持,所以我不能简单地将它添加为 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;
检查我的泛型类型是否支持某个接口**然后如果是,那么推荐的方法是什么
-
在方法中使用它来过滤集合
但仍然在整体方法中返回类型为“T”的集合
注意: FilterByTeams 接受:
IEnumerable<ITeamFilterable>
AND 返回
IEnumerable<ITeamFilterable>
我是否需要将集合转换 2 次(一次转换为接口列表,然后再次转换回 T 列表?)
【问题讨论】:
或者只使用is
/ as
+ != null
。 ***.com/questions/410227/…
这不是重复的,因为链接的问题不涉及协方差
【参考方案1】:
恐怕在这种情况下你不能使用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
以满足泛型约束。使用这些演员表,无需复制项目。
【讨论】:
查看我的问题的更新。您的答案不起作用,因为 FilterByTeams 不返回 T 集合,而是返回 ITeamFilterable 接口的集合 @leora 答案已更新,这应该可以工作 所以你的答案,简而言之,是的,你需要来回投射 简而言之,是的。但我的观点是,您不需要仅仅为了拥有ITeamFilterable
的列表而创建ITeamFilterable
的新列表,演员阵容就足够了,并且不会复制数据。我想我误解了你问题的这方面。以上是关于如何判断我的泛型类型是不是支持某个接口并为函数来回转换到该接口? [复制]的主要内容,如果未能解决你的问题,请参考以下文章