代码之家  ›  专栏  ›  技术社区  ›  Paul Suart Wes

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

  •  4
  • Paul Suart Wes  · 技术社区  · 17 年前

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

    public interface IGenericRelation<TParent, TChild> : IRelation
    
    public interface IRelation
    

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

    但我真正想做的是。。。

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

    relationControl 使用它当时提供的类型,我可以访问IGenericRelation上可用的强类型属性。不幸的是,这是不可能的,因为我似乎不能忽略类型参数。

    有人知道如何枚举实现通用接口的控件,以避免我必须编写多个循环而不是一个循环吗?也许使用反射?

    2 回复  |  直到 17 年前
        1
  •  3
  •   Adam Robinson    17 年前

    这是不可能的,因为 IGenericRelation<T,F> 是一种完全不同于 IGenericRelation<G,I> IGenericRelation ,则您需要在 IRelation 层,或在 关联 IGenericRelation<,> 这实现了这些。原因是编译器无法推断期望实现的类型。

    object 在更高的级别(或者 关联 数量

        2
  •  1
  •   Martin Harris    17 年前

    您正在尝试访问哪些强类型属性?如果它们是强类型的,因为它们是泛型的输入类型,那么如果不在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类一样是独立的,因此请求“以此模板开头的所有类”是没有意义的,您最好的办法是寻找一个共享基类或接口—在本例中是IRRelation。