如何枚举实现通用接口的所有项目?

我有两个接口,一个generics和一个非generics,具有inheritance层次结构:

public interface IGenericRelation : IRelation public interface IRelation 

通用的是由几个动态加载的服务器控件实现的,我希望枚举实现此接口的控件集合。 我可以做以下事情

  foreach (IRelation relationControl in this.uiPlhControls.Controls.OfType<IRelation) { ... } 

但我真正希望能做的是……

  foreach (IGenericRelation relationControl in this.uiPlhControls.Controls.OfType<IGenericRelation) { ... } 

然后能够将relationControl与它提供的类型一起使用,然后我就可以访问IGenericRelation上可用的强类型属性。 不幸的是,这是不可能的,因为我似乎无法省略类型参数。

有没有人知道枚举实现通用接口的控件的方法,以防止我必须编写几个循环而不是一个循环? 或许使用reflection?

这是不可能的,因为IGenericRelation是与IGenericRelation完全不同的类型。 如果您需要访问所有IGenericRelation的特定属性,那么您需要在IRelation层实现它们,或者在IRelation和实现这些的IGenericRelation<,>之间引入第三个接口。 这样做的原因是编译器无法推断出要实现的类型。

最简单的方法是将两个属性实现为更高级别的objectIRelation或中间接口),并在IGenericRelation<,>级别强类型化。

您尝试访问哪些强类型属性? 如果它们是强类型的,因为它们是generics的输入类型,那么如果不在foreach循环中提供类型,您将无法访问它们。 如果它们是强类型的,但与提供的类型无关,您可以将它们移动到IRelation类吗?

使用代码示例会更有意义 – 让我们说你的类是这样的:

 public IRelation { public string RelationshipType { get; set; } } public IGenericRelation : IRelation { public TParent Parent { get; set; } public TChild Child { get; set; } } 

如果您的列表包含一个IGenericRelation和一个IGenericRelation ,则无法在不知道您要查找的具体类型的情况下枚举并获取两者:

 //Theoretical, non-compiling example.... foreach (IGenericRelation<,> relationControl in this.uiPlhControls.Controls.OfType>) { //This wouldn't work for type IGenericRelation relationControl.Parent.FooProperty = "Wibble"; //You would be able to access this, but there is no advantage over using IRelation relationControl.RelationshipType = "Wibble"; } 

(请注意,我还必须从示例代码中更改foreach中的relationControl类型,以便可能的用法有所帮助。)


从根本上说,将.NETgenerics与C ++模板类相同可能会有所帮助(我知道实现是不同的,但在这方面的效果是相同的)。 想象一下,在编译时,将检查所有代码是否使用IGenericRelation类,并通过对TParent和TChild关键字执行查找并将其替换为请求的类型来创建具体的非generics类。 由于两个创建的类与任何其他两个.NET类是分开的,因此请求“所有以该模板开头的类”是没有意义的,您可以做的最好的事情是查找共享基类或接口 – 在这种情况下IRelation。