2011-05-20 67 views
6

我想使用OfType <>来过滤List<ISeries>中的对象。我的问题是,某些对象是通用接口类型,但它们没有自己的共同继承接口。

我有以下定义:如何使用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或网上找到有用的信息。感谢帮助!

+2

想想'myList.OfType'的返回类型应该是什么。 – 2011-05-20 11:38:27

+0

它应该是IEnumerable 。但是这是一个好点,如何告诉OfType <>方法!? – Marcel 2011-05-20 11:41:42

+1

OfType的返回类型与类型参数相同。 – 2011-05-20 11:44:21

回答

5

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

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

好东西!不过,我想,我可以减少复杂性......现在我的复杂性隐藏在一个远程空间中,而不是在继承结构中! :-) – Marcel 2011-05-20 12:32:37

+0

你能告诉我什么类型(ITraceSeries <>)实际返回类型?据我所知,泛型类不共享一个通用的基类。 (这首先是我的麻烦来源) – Marcel 2011-05-20 12:36:39

+0

@Marcel:'typeof(ITraceSeries <>)'为'ITraceSeries '返回一个开放的泛型类型。您不能声明该类型的对象,但可以使用它来创建类似“ITraceSeries ”的封闭类型。 – 2011-05-20 13:39:18

1
from s in series 
where s.GetType().GetGenericTypeDefinition()==typeof(ITraceSeries<>) 
select s; 
+0

好主意,但它不会像这样工作,因为'typeof(ITraceSeries )!= typeof(ITraceSeries <>)'。修复。 – 2011-05-20 11:42:55

+0

:-)许多答案只是想法 - 正确的解决方案。感谢您的纠正。 – VikciaR 2011-05-20 11:48:47

+0

@Martinho:这仍然不起作用,因为'GetType'将返回一个具体的运行时类型,该类型永远不会是'ITraceSeries ',它将是'ITraceSeries '的具体实现。请参阅我的答案,以获得应该满足OP要求的解决方案。 – LukeH 2011-05-20 11:50:19

相关问题