【问题标题】:How to filter to all variants of a generic type using OfType<>如何使用 OfType<> 过滤到泛型类型的所有变体
【发布时间】:2016-03-22 19:06:07
【问题描述】:

我想过滤 List&lt;ISeries&gt; 中的对象,使用它们的类型,使用 OfType。 我的问题是,有些对象是通用接口类型,但它们没有共同的接口类型继承了自己的接口。

我有以下定义:

public interface ISeries
public interface ITraceSeries<T> : ISeries
public interface ITimedSeries : ISeries
//and some more...

我的列表包含各种ISeries,但现在我只想获取ITraceSeries 对象,而不考虑它们实际定义的泛型类型参数,如下所示:

var filteredList = myList.OfType<ITraceSeries<?>>(); //invalid argument!

我该怎么做?

一个不受欢迎的解决方案是引入一个继承自 ISeries 的类型 ITraceSeries

public interface ITraceSeries<T> : ITraceSeries

然后,使用ITraceSeries 作为过滤器。但这并没有真正增加新的信息,只会让继承链更加复杂。

在我看来这是一个常见问题,但我没有在 SO 或网络上找到有用的信息。感谢您的帮助!

【问题讨论】:

  • 想想myList.OfType的返回类型应该是什么。
  • 它应该是 IEnumerable。但这是一个好点,如何告诉 OfType 方法!?
  • OfType的返回类型与类型参数一致。
  • @Martinho Nit:它返回类型参数的 IEnumerable

标签: c# linq generics filter oftype


【解决方案1】:

你可以使用反射来实现它:

var filteredList = myList.Where(
    x => x.GetType()
          .GetInterfaces()
          .Any(i => i.IsGenericType && (i.GetGenericTypeDefinition() == typeof(ITraceSeries<>))));

【讨论】:

  • 好东西!但是,我想,我可以降低复杂性……现在我的复杂性隐藏在一个远程空间中,而不是在继承结构中! :-)
  • 你能告诉我 typeof(ITraceSeries) 实际上返回的类型是什么吗?据我所知,泛型类型类不共享一个公共基类。 (这首先是我的麻烦)
  • @Marcel: typeof(ITraceSeries&lt;&gt;)ITraceSeries&lt;T&gt; 返回一个开放的泛型类型。您不能声明该类型的对象,但可以使用它来创建封闭类型,例如 ITraceSeries&lt;string&gt;
  • @Martinho:为了挑剔,从技术上讲 typeof> 更好地描述为 unbound 泛型类型。一个类型是开放的还是封闭的,取决于它里面是否有任何未替换的类型参数;例如,I 是绑定但打开的。 I 绑定和关闭,I 未绑定。
【解决方案2】:
from s in series
where s.GetType().GetGenericTypeDefinition()==typeof(ITraceSeries<>)
select s;

【讨论】:

  • 好主意,但由于typeof(ITraceSeries&lt;string&gt;) != typeof(ITraceSeries&lt;&gt;),它不会完全那样工作。修好了。
  • :-) 大部分答案都只是想法——找到正确解决方案的方向。谢谢指正。
  • @Martinho:这仍然行不通,因为GetType 将返回一个具体的运行时类型,并且该类型永远不会是ITraceSeries&lt;something&gt;,它将是ITraceSeries&lt;something&gt; 的具体实现。请参阅我的答案以获取应该满足 OP 要求的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-04
  • 1970-01-01
  • 2022-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-21
相关资源
最近更新 更多