3

我在带有 C# 8 的 .NET Core 3.1 中有这个简单的控制台程序:

using System;

namespace ConsoleApp34
{

    public interface ITest
    {
        public void test()
        {
            Console.WriteLine("Bye World!");

        }
    }

    public class Test : ITest
    {
        public void CallDefault()
        {
            ((ITest)(this)).test();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            var t = new Test();
            t.CallDefault();

        }
    }
}

我不明白为什么演员阵容是必要的((ITest)(this)).test();

Test 直接派生自 ITest,因此,根据定义,'this' IS ITest

谢谢你。

4

2 回答 2

7

默认接口实现的工作方式与显式实现类似:它们只能通过接口类型调用,而不能通过实现类型调用。

要理解为什么会这样,想象一下Test实现了两个具有相同方法签名的接口;如果没有演员表,将使用哪个?

public interface ITest2
{
    public void test()
    {
        Console.WriteLine("Hello World!");
    }
}

public class Test : ITest, ITest2
{
    public void CallDefault()
    {
        test(); // Do we use ITest.test() or ITest2.test()?
    }
}
于 2020-08-14T12:56:38.037 回答
2

此处记录了此行为。

从 C# 8.0 开始,您可以为接口中声明的成员定义实现。如果类从接口继承方法实现,则只能通过接口类型的引用访问该方法。继承的成员不会作为公共接口的一部分出现。以下示例定义了接口方法的默认实现:

public interface IControl
{
    void Paint() => Console.WriteLine("Default Paint method");
}
public class SampleClass : IControl
{
    // Paint() is inherited from IControl.
}

以下示例调用默认实现:

var sample = new SampleClass();
//sample.Paint();// "Paint" isn't accessible.
var control = sample as IControl;
control.Paint();

任何实现 IControl 接口的类都可以覆盖默认的 Paint 方法,或者作为公共方法,或者作为显式接口实现。

于 2020-08-14T12:57:34.037 回答