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

C# 如何枚举实现通用接口的所有项?,c#,generics,reflection,collections,C#,Generics,Reflection,Collections,我有两个接口,一个通用接口和一个非通用接口,它们具有继承层次结构: public interface IGenericRelation<TParent, TChild> : IRelation public interface IRelation 公共接口IGenericRelation:IRelation 公共接口关系 通用的一个由几个动态加载的服务器控件实现,我希望列举实现此接口的控件集合。我可以做到以下几点 foreach (IRelation relationC

我有两个接口,一个通用接口和一个非通用接口,它们具有继承层次结构:

public interface IGenericRelation<TParent, TChild> : IRelation

public interface IRelation
公共接口IGenericRelation:IRelation
公共接口关系
通用的一个由几个动态加载的服务器控件实现,我希望列举实现此接口的控件集合。我可以做到以下几点

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

foreach(i此.uiPlhControls.Controls.OfType中的IRRelation Relational Control您试图访问哪些强类型属性?如果它们是强类型属性,因为它们是泛型的输入类型,那么您将无法访问它们,而无需在foreach循环中提供类型。如果它们是强类型属性,但与提供的你能把它们移到IRelation类吗

对于代码示例,这将更有意义-假设您的类类似于:

public IRelation
{
   public string RelationshipType { get; set; }
}

public IGenericRelation<TParent, TChild> : IRelation
{
    public TParent Parent { get; set; }
    public TChild Child { get; set; }
}
公共关系
{
公共字符串关系类型{get;set;}
}
公共IGenericRelation:IRelation
{
公共TParent父项{get;set;}
公共TChild子项{get;set;}
}
如果您的列表中包含一个
IGenericRelation
和一个
IGenericRelation
,则在不知道要查找的具体类型的情况下,您无法枚举并获取这两个:

//Theoretical, non-compiling example....
foreach (IGenericRelation<,> relationControl in this.uiPlhControls.Controls.OfType<IGenericRelation<,>>)
{ 
    //This wouldn't work for type IGenericRelation<Fizz, Buzz>
    relationControl.Parent.FooProperty = "Wibble";

    //You would be able to access this, but there is no advantage over using IRelation
    relationControl.RelationshipType = "Wibble";
}
//理论上的非编译示例。。。。
foreach(此.uiPlhControls.Controls.OfType中的IGenericRelationRelationControl)
{ 
//这对于类型IGenericRelation不起作用
relationControl.Parent.FooProperty=“Wibble”;
//您可以访问这个,但是使用IRelation没有任何优势
relationControl.RelationshipType=“Wibble”;
}
(注意,我还必须根据示例代码更改foreach中relationControl的类型,以便可能的用法有一定的意义。)



<>基本上可以认为.NET泛型与C++模板类一样(我知道实现是不同的,但在这方面的效果是一样的)。假设在编译时检查所有代码是否使用IGenericRelation类,并通过查找TParent和TChild关键字并将其替换为请求的类型来创建具体的、非泛型的类。由于创建的两个类与其他任何两个.NET类一样独立,因此请求没有任何意义“以此模板开头的所有类”,您所能做的最好的事情就是查找共享基类或接口—在本例中为IRelation。

这是不可能的,因为
IGenericRelation
是与
IGenericRelation
完全不同的类型。如果您需要访问所有
IGenericRelation
通用的特定属性,则您需要导入在
IRelation
层删除它们,或者在
IRelation
IGenericRelation
之间引入第三个接口来实现它们。原因是编译器无法推断期望实现的类型


实现这一点最简单的方法是在更高的级别(或者
ireation
或者中间接口)将两个属性实现为
对象在
IGenericRelation
级别进行强类型输入。

我似乎记得早期的Linq示例就是这样做的,但当我查看Linq时,我找不到它。我正在观察这个空间……是的,它们是通用接口的输入类型。
//Theoretical, non-compiling example....
foreach (IGenericRelation<,> relationControl in this.uiPlhControls.Controls.OfType<IGenericRelation<,>>)
{ 
    //This wouldn't work for type IGenericRelation<Fizz, Buzz>
    relationControl.Parent.FooProperty = "Wibble";

    //You would be able to access this, but there is no advantage over using IRelation
    relationControl.RelationshipType = "Wibble";
}