C# 如何正确反映基本接口方法
我有2个接口和2个类,我通过反射进行研究: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
- IParent
- IChild-源自IParent
- 母公司
- 子-源于父
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不,这不是打字错误。仅显示反映继承类与接口的差异。