如何枚举所有实现泛型接口的项?

4

我有两个界面,一个通用界面和一个非通用界面,它们具有继承关系:

public interface IGenericRelation<TParent, TChild> : IRelation

public interface IRelation

通用接口由几个动态加载的服务器控件实现,我希望枚举实现此接口的控件集合。我可以执行以下操作:

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

但我真正想做的是能够...(涉及IT技术,具体内容需要根据上下文进行翻译)
    foreach (IGenericRelation<,> relationControl in this.uiPlhControls.Controls.OfType<IGenericRelation<,>)
    { ... }

然后我就可以使用relationControl以其提供的类型,这样我就能够访问IGenericRelation上可用的强类型属性。不幸的是,由于无法省略类型参数,这是不可能的。

有没有人知道一种枚举实现通用接口的控件的方法,以防止我不得不写几个循环而不是一个?也许可以使用反射?


我似乎记得早期的Linq示例正是这样做的,但当我查看Linq时找不到它。我会继续关注这个领域... - Binary Worrier
2个回答

3
这是不可能的,因为IGenericRelation<T,F>IGenericRelation<G,I>是完全不同的类型。如果需要访问所有IGenericRelation共有的特定属性,您需要在IRelation层实现这些属性,或在IRelationIGenericRelation<,>之间引入第三个接口来实现这些属性。原因是编译器无法推断它要实现什么类型。
最简单的方法是将您的两个属性作为一个object在更高的级别(IRelation或中间接口)上实现,并在IGenericRelation<,>级别上强制类型化。

1
你试图访问哪些强类型属性?如果它们是强类型,因为它们是泛型的输入类型,那么在foreach循环中不提供类型就无法访问它们。如果它们是强类型,但与提供的类型无关,你可以将它们移动到IRelation类中吗?
这将通过代码示例更加清晰 - 假设你的类类似于:
public IRelation
{
   public string RelationshipType { get; set; }
}

public IGenericRelation<TParent, TChild> : IRelation
{
    public TParent Parent { get; set; }
    public TChild Child { get; set; }
}

如果您的列表包含一个 IGenericRelation<Foo, Bar> 和一个 IGenericRelation<Fizz, Buzz>,则在不知道您要查找哪种具体类型的情况下,您无法枚举并获取两者。
//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中relationControl的类型,以使可能的使用有些意义。)

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


是的,它们是通用接口的输入类型。 - Paul Suart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接