首页 > 解决方案 > C#调用接口方法非虚实现

问题描述

我是 C# 新手,我不明白为什么编译器不会抱怨这段代码。这是类的层次结构:

interface IAble
{
    void f();
}

class AAble : IAble
{
    public void f()
    {
        Debug.Log("---->> A - Able");
    }
}

class BAble : AAble
{
    public void f()
    {
        Debug.Log("---->> B - Able");
    }
}

执行代码:

        IAble i = new BAble();
        i.f();

执行---->> A - Able时打印。为什么?编译器如何知道应该调用什么函数?

当决定调用什么函数时——运行时还是编译时?如果我玷污了一个新班级class CAble : IAble怎么办?

标签: c#interfacenon-virtual-interface

解决方案


因为AAble正在实现IAble接口,所以将其AAble.f标记IAble.f为 type 方法的实现AAble

BAble.f只是隐藏AAble.f方法,而不是覆盖它。

IAble o = new BAble(); o.f(); // calls AAble.f
AAble o = new BAble(); o.f(); // calls AAble.f
BAble o = new BAble(); o.f(); // calls BAble.f
IAble o = new CAble(); o.f(); // calls CAble.f

决定是在编译时做出的:

// AAble.f in IL:
.method public final hidebysig newslot virtual 
    instance void f () cil managed 

// BAble.f in IL:
.method public hidebysig 
    instance void f () cil managed

接口实现virtual在 IL 中被标记为,即使它在 C# 中没有被标记为虚拟。该方法final在 IL 中也被标记为,如果该方法virtual在 C# 中,则不会被标记为final.


推荐阅读