如何判断我的泛型类型是不是支持某个接口并为函数来回转换到该接口? [复制]

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;

转换将起作用,因为 ITeamFilterableT 并且 IEnumerable&lt;T&gt; 是协变的,但您必须在两者之间转换为 object 以满足泛型约束。使用这些演员表,无需复制项目。

【讨论】:

查看我的问题的更新。您的答案不起作用,因为 FilterByTeams 不返回 T 集合,而是返回 ITeamFilterable 接口的集合 @leora 答案已更新,这应该可以工作 所以你的答案,简而言之,是的,你需要来回投射 简而言之,是的。但我的观点是,您不需要仅仅为了拥有ITeamFilterable 的列表而创建ITeamFilterable 的新列表,演员阵容就足够了,并且不会复制数据。我想我误解了你问题的这方面。

以上是关于如何判断我的泛型类型是不是支持某个接口并为函数来回转换到该接口? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

java如何判断一个类是不是实现了某个接口?

受保护的泛型类 - 是不是支持?

为啥在接口列表的泛型类型中使用私有嵌套类型不是“不一致的可访问性”?

Java基础——Java中的泛型(值得一看)

如何在接口中声明可选的泛型类型?

将接口上的泛型参数限制为子类