【问题标题】:Why is the members of an inherited interface not available using reflection?为什么继承接口的成员不能使用反射获得?
【发布时间】:2009-11-23 14:18:19
【问题描述】:

在对接口类型进行反射时,我只获取特定类型的成员,而不是继承的成员。

在这个过于简化的示例中,程序只打印“Name”,而不是“ItemNumber”,“Name”,正如我所期望的那样:

using System;

public interface IBasicItem
{
    string ItemNumber { get; set; }
}

public interface IItem : IBasicItem
{
    string Name { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var type = typeof (IItem);
        foreach (var prop in type.GetProperties())
            Console.WriteLine(prop.Name);
    }
}

这背后的原理是什么?当我从基接口继承时,我是说我的接口的任何实现都必须实现继承的成员。换句话说,IItem is-a IBasicItem。那么为什么继承的成员不使用反射显示呢?

【问题讨论】:

    标签: c# reflection


    【解决方案1】:

    我认为这正是 Phil Haack 刚刚写的博客。

    来自 ECMA-335 公共语言基础设施规范:

    8.9.11 接口类型派生接口类型可以要求 实施一项或多项其他 接口。任何实现的类型 对接口类型的支持应 还实现对任何 指定的所需接口 界面。这不同于 对象类型继承有两种方式:

    • 对象类型形成一个单一的继承树;接口类型做 不是。
    • 对象类型继承指定如何继承实现; 不需要的接口,因为 接口不定义 执行。所需接口 指定附加合同 实现对象类型应 支持。

    突出显示最后一个 区别,考虑一个接口, IFoo,只有一个方法。一个 接口,IBar,它派生自 它,要求任何对象类型 支持 IBar 的也支持 IFoo。 它没有说什么 IBar 本身将具有的方法。

    引用自: http://haacked.com/archive/2009/11/10/interface-inheritance-esoterica.aspx

    【讨论】:

    • Doh...我可以看出我今天早上很困。为正确答案 +1。
    【解决方案2】:

    考虑这一点的一个好方法是接口不像类那样具有“继承”。继承意味着“是一种”的关系,而接口“继承”实际上意味着“需要提供这个服务”的关系。

    当我们说

    interface IEnumerator<T> : IDisposable
    

    我们所说的与其说是“序列枚举器是一种一次性的东西”,不如说是“如果你提供枚举器服务,那么你必须提供 dispose 服务”。

    现在更有意义了吗?

    【讨论】:

      【解决方案3】:

      这是因为您正在使用接口。接口的继承结构与类不同。

      如果您有一个实现这些接口的类,您将看到正确的链(假设您使用“BindingFlags.FlattenHierarchy”)。

      尝试创建一个实现较低级别接口的类,您应该会看到要查找的内容。

      【讨论】:

        【解决方案4】:

        这是因为你没有要求你想知道的信息。换句话说,由于您继承的属性与从接口获得的属性具有不同的含义,因此您必须以不同的方式访问它们。

        因此,您可以像这样通过反射访问:

        foreach ( var iface in type.GetInterfaces() )
        {
          foreach ( var prop in iface.GetProperties() )
          {
            Console.WriteLine( iface.Name +"-"+ prop.Name );
          }
        }
        

        由于类继承与接口合规性不同,因此以不同方式访问它们似乎是合乎逻辑的。

        【讨论】:

          猜你喜欢
          • 2014-09-06
          • 2011-05-21
          • 1970-01-01
          • 1970-01-01
          • 2014-06-01
          • 2014-09-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多