C# 如何正确反映基本接口方法

C# 如何正确反映基本接口方法,c#,inheritance,reflection,interface,C#,Inheritance,Reflection,Interface,我有2个接口和2个类,我通过反射进行研究: IParent IChild-源自IParent 母公司 子-源于父 对我来说奇怪的是,当我查看IChild类型的反射时,我没有找到iPart方法 应用于子类型的代码与预期的相同-反射显示父方法 interface IParent { void ParentMethod(); } interface IChild : IParent { void ChildMethod(); } class Parent { p

我有2个接口和2个类,我通过反射进行研究:

  • IParent
  • IChild-源自IParent
  • 母公司
  • 子-源于父
对我来说奇怪的是,当我查看IChild类型的反射时,我没有找到iPart方法

应用于子类型的代码与预期的相同-反射显示父方法

interface IParent
{
     void ParentMethod();
}

interface IChild : IParent
{
     void ChildMethod();
}

class Parent 
{
     public void ParentMethod(){}
}

class Child : Parent
{
     public void ChildMethod(){}
}

void Main()
{
    //investigate derived interface
     Type t = typeof(IChild);
     var info = t.GetMethod("ChildMethod");//ok
     Console.WriteLine(info); 
     info = t.GetMethod("ParentMethod");//returns null!
     Console.WriteLine(info); 
     //investigate derived class
     t = typeof(Child);
     info = t.GetMethod("ChildMethod");//ok
     Console.WriteLine(info);
     info = t.GetMethod("ParentMethod");//ok
     Console.WriteLine(info);
}
请解释一下这种行为


是否有任何变通方法可以从派生接口的类型反映基本接口的方法?

尽管如此,我们使用接口的方式与使用继承(“:”)的方式相同;接口不是继承的;它们将得到实施。在这种情况下;继承与实现混淆,因为它们是使用相同的运算符(“:”)定义的

作为总结;
IA:IB
A:IA
表示:;在这种情况下,任何实现IA的类都应实现IB;A应实施IA和IB

A:B
表示一个类继承了B类;它没有实现

这里的混淆源于使用相同的运算符(“:”)

检查此页面

接口的基本接口(在本例中,
iPart
IChild
的基本接口)是显式的基本接口。对于接口来说,继承是一个不幸的词,因为类、结构和其他接口从不从接口继承,它们只是实现基本接口定义的契约

当您从
iPart
派生
IChild
时(注意我没有说继承),它没有定义
ParentMethod
方法,它只是说实现我的任何东西,也必须实现
iPart

当您考虑实际类型时,它工作的原因是因为实现接口实际上在类型本身中定义了方法签名,而接口则不是这样

这是由于编译器发生了一个称为接口映射的过程,该过程被定义为在实现类或结构中定位接口成员的过程,但接口本身不会发生这种情况

反射接口时,不会发生接口映射,因此只反射接口本身

Type t = typeof(IChild);
类型信息将仅明确包含关于
IChild
的类型信息

Type t = typeof(Child);
这里确实发生了接口映射过程。当您考虑名为
ParentMethod
的方法的
子类
类型时,将检查每个基本接口,直到找到匹配项

这部分的语言设计。您可以在C#Programming Language(第四版)第13.1.4节或ECMA规范第20.1.2节中了解更多信息

您可以通过重新实现接口来解决这个问题,但它需要一些额外的代码

interface IParent
{
    void ParentMethod();
}

interface IChild
{
    new void ParentMethod(); // Reimplement IParent.ParentMethod()
    void ChildMethod();
}
这会奏效的

Type t = typeof(IChild);
MethodInfo mi = t.GetMethod("ParentMethod");

由于重新实现了接口,
IChild
现在包含一个方法签名
ParentMethod
如果您正在处理接口,请使用

t.GetInterfaces()
然后可以检查上面返回的类型的方法


按名称查找接口成员是不可靠的,请注意,在C#中,接口成员在实现时不能重命名,但在CLR中,名称可能会被修改。(IDisposable.Dispose()有时重命名为Close)。在il中有一条名为
的指令。实现了允许更改名称的
。我相信VB.Net也有这个功能。

Parent
没有实现
iPart
…输入错误?好问题。通过阅读答案,我学到了一些东西。还不需要知道,但知识就是力量…@Jamiec不,这不是打字错误。仅显示反映继承类与接口的差异。