从具有相同名称的显式接口函数调用类函数

发布于 2025-02-07 15:18:21 字数 524 浏览 3 评论 0 原文

随附的代码按预期工作,它打印“某物!”, 但是定义行为(从“显式”方法调用“正常”方法)?

我搜索了“显式接口调用方法/函数”的各种组合,但是我所能找到的只是有关隐式和明确定义的接口函数之间差异的示例,以及如何调用明确定义的函数。

interface ISomething
{
    void DoSomething();
}
class Something : ISomething
{
    private void DoSomething()
    {
        Console.WriteLine("Something!");
    }

    void ISomething.DoSomething()
    {
        DoSomething();
    }

    public static void Main()
    {
        ISomething thing = new Something();
        thing.DoSomething();
    }
};

The attached code works as expected, it prints 'Something!',
but is it defined behaviour (to call the 'normal' method from the 'explicit' method)?

I have searched for various combinations of 'explicit interface call method/function', but all I could find were examples about the difference between implicit and explicitly defined interface functions, and how to call an explicitly defined function.

interface ISomething
{
    void DoSomething();
}
class Something : ISomething
{
    private void DoSomething()
    {
        Console.WriteLine("Something!");
    }

    void ISomething.DoSomething()
    {
        DoSomething();
    }

    public static void Main()
    {
        ISomething thing = new Something();
        thing.DoSomething();
    }
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

罪#恶を代价 2025-02-14 15:18:21

无论事情如何工作,您的代码都将具有相同的输出。我建议使用下一个以更清楚地理解:

class Something : ISomething
{
    private void DoSomething()
    {
        Console.WriteLine("Something!");
    }

    void ISomething.DoSomething()
    {
        Console.WriteLine("Explicit Something!");
    }
};

哪些将打印出明确的东西!为您的 main 。至于为什么两个实施 - 作为C#7.0规格草案 state

在方法,属性访问,事件访问或索引器访问中,不可能通过其合格接口成员名称访问显式接口成员实现。 明确的接口成员实现只能通过接口实例访问,并且在这种情况下仅以其成员名称引用。

因此 dosomething()在原始 isomething.dosomething()实现中呼叫 sosity.dosomething(),而不是 .dosomething() isomething.dosomething()是不可访问的原因,因为它需要接口实例。如果您重命名 isomething.dosothing isomething.dosomething1 ,您会看到它在 isomething> isomething.dosomething.dosomething.dosomething 1 call除非施放代码> this 到接口:

interface ISomething
{
    void DoSomething1();
}

class Something : ISomething
{
    public void DoSomething()
    {
        Console.WriteLine("Something!");
    }

    void ISomething.DoSomething1()
    {
        // DoSomething1(); // The name 'DoSomething1' does not exist in the current context
        // ((ISomething)this).DoSomething1(); // will obviously end in SO
        Console.WriteLine("ISomething.DoSomething1!");
    }
}

也可以很有用接口映射部分:

接口映射算法的显着含义为:

  • 在确定实现接口成员的类或结构成员时,显式接口成员实现优先于同一类或结构的其他成员。
  • 非公共和静态成员都不参加接口映射。

Your code will have the same output no matter how things work. I suggest using next for clearer understanding:

class Something : ISomething
{
    private void DoSomething()
    {
        Console.WriteLine("Something!");
    }

    void ISomething.DoSomething()
    {
        Console.WriteLine("Explicit Something!");
    }
};

Which will print Explicit Something! for your Main. As for why for both implementations - as draft C# 7.0 specification states:

It is not possible to access an explicit interface member implementation through its qualified interface member name in a method invocation, property access, event access, or indexer access. An explicit interface member implementation can only be accessed through an interface instance, and is in that case referenced simply by its member name.

So DoSomething() call in original ISomething.DoSomething() implementation is call to the Something.DoSomething() and not to ISomething.DoSomething(). ISomething.DoSomething() is no accessible cause it requires an interface instance. If you rename ISomething.DoSomething to for example ISomething.DoSomething1 you will see that it is not accessible inside ISomething.DoSomething1 call unless you cast this to interface:

interface ISomething
{
    void DoSomething1();
}

class Something : ISomething
{
    public void DoSomething()
    {
        Console.WriteLine("Something!");
    }

    void ISomething.DoSomething1()
    {
        // DoSomething1(); // The name 'DoSomething1' does not exist in the current context
        // ((ISomething)this).DoSomething1(); // will obviously end in SO
        Console.WriteLine("ISomething.DoSomething1!");
    }
}

Also can be useful interface mapping section:

Notable implications of the interface-mapping algorithm are:

  • Explicit interface member implementations take precedence over other members in the same class or struct when determining the class or struct member that implements an interface member.
  • Neither non-public nor static members participate in interface mapping.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文