繁体   English   中英

当我在 class 派生形式的接口中调用它时,为什么需要将“this”强制转换为 C# 8.0 中具有默认实现的接口?

[英]Why do I need to cast 'this' to an interface with a default implementation in C# 8.0 when I call it in the class derived form that interface?

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

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' 是 ITest

谢谢你。

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

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

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()?
    }
}

此处记录了此行为。

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

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 接口的 class 都可以覆盖默认的 Paint 方法,或者作为公共方法,或者作为显式接口实现。

有趣的是,如果您创建了一个扩展方法,那么就不再需要强制转换了。

刚刚在我的项目中做了以下事情:

public static class IXpObjectExtensions
{
    public static Mode GetMode(this IXpObject obj) => obj.Mode;
}

在我的例子中,模式是用 IXpObject 中的默认实现定义的。
我现在可以使用obj.GetMode()而无需将 object 转换为接口。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM