如何正确反映基本接口方法
本文关键字:接口 方法 何正确 | 更新日期: 2023-09-27 18:33:56
我有 2 个接口和 2 个类,我通过反射进行研究:
- IParent
- IChild - 源自 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
表示 A 类继承 B 类;它不实现。
此处的混淆源于使用相同的运算符 (":"(。
检查此页面接口继承
如果您正在处理接口,请使用
t.GetInterfaces()
然后,您可以检查上面返回的类型的方法。
按名称查找接口成员是不可靠的,请注意,虽然在 C# 中接口成员不能在实现时重命名,但在 CLR 中,名称可能会被修改。(IDisposable.Dispose(( 有时会重命名为 Close(。在 il 有一条名为 .implements
的指令,允许人们更改名称。我相信 VB.Net 也有这个功能。
的基本接口(在本例中IParent
是IChild
的基本接口(是显式的基本接口。继承对于接口来说是一个不幸的词,因为类、结构和其他接口从不从接口继承,它们只是实现基接口定义的协定。
当你从IParent
派生IChild
时(注意我没有说继承(,它没有定义ParentMethod
方法,它只是说任何实现我的东西,也必须实现IParent
。
当您反映实际类型时,它之所以有效,是因为实现接口实际上确实在类型本身中定义了该方法签名,而接口并非如此。
这是由于编译器发生的称为接口映射的过程,该过程定义为在实现类或结构中查找接口成员的过程,但接口本身不会发生这种情况。
当您反思接口时,不会发生接口映射,因此只会反映接口本身。
Type t = typeof(IChild);
类型信息将仅包含显式有关IChild
的类型信息。
Type t = typeof(Child);
这里确实发生了接口映射的过程。当您考虑名为 ParentMethod
的方法的Child
类型时,将检查每个基接口,直到找到匹配项。
这部分语言设计。您可以在 C# 编程语言(第四版(的第 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
的方法签名。