隐藏(使用"new"修饰符)接口方法声明的目的是什么?

Pra*_*eek 13 c# interface new-operator

可以将接口中的方法声明标记为" new ",但它是否具有任何"技术"意义,或者它只是一种明确声明声明不能覆盖前一个声明的方法?

例如 :

interface II1
{
    new void F();
}

interface II2 : II1
{
    new void F();
}
Run Code Online (Sandbox Code Playgroud)

是有效的(C#4.0编译器不会抱怨)但似乎与以下内容不同:

interface II1
{
    void F();
}

interface II2 : II1
{
    void F();
}
Run Code Online (Sandbox Code Playgroud)

提前感谢您提供任何信息.

编辑:你知道一个隐藏在界面中会有用的场景吗?

编辑:根据这个链接:方法隐藏是一个好主意(感谢斯科特),最常见的情况似乎是协变返回类型的模拟.

Fre*_*örk 8

第二个示例发出以下编译器警告:

'II2.F()'隐藏了继承成员'II1.F()'.如果要隐藏,请使用new关键字.

我会说使用new关键字的不同之处在于:显示意图.


Pau*_*ane 6

两者非常不同.通过使用'new',您将创建一个新的继承链.这意味着任何实现II2都需要实现两个版本F(),并且最终调用的实际版本将取决于引用的类型.

考虑以下三种实现:

    class A1 : II1
    {
        public void F()
        {
            // realizes II1.F()
        }
    }

    class A2 : II2
    {
        void II1.F()
        {
            // realizes II1.F()
        }

        void II2.F()
        {
            // realizes II2.F()
        }
    }

    class A3 : II2
    {
        public void F()
        {
            // realizes II1.F()
        }

        void II2.F()
        {
            // realizes II2.F()
        }
    }
Run Code Online (Sandbox Code Playgroud)

如果你有参考A2,你将无法在F()没有首先投射到II1或之前调用任何一个版本II2.

A2 a2 = new A2();
a2.F(); // invalid as both are explicitly implemented
((II1) a2).F(); // calls the II1 implementation
((II2) a2).F(); // calls the II2 implementation
Run Code Online (Sandbox Code Playgroud)

如果您有引用A3,则可以II1直接调用该版本,因为它是隐式实现:

A3 a3 = new A3();
a3.F(); // calls the II1 implementation
((II2) a3).F(); // calls the II2 implementation
Run Code Online (Sandbox Code Playgroud)

  • 请注意,问题中给出的两个示例之间的编译代码没有区别.您解释的差异是方法隐藏的效果,但无论是否使用`new`关键字,它都会发生. (2认同)

Han*_*ant 5

我知道这样做的一个很好的用途:您必须这样做才能声明从另一个 COM 接口派生的 COM 接口。本杂志文章中提到了这一点。

Fwiw,作者完全错误地识别了问题的根源,它与“遗产税”无关。COM 只是利用典型 C++ 编译器实现多重继承的方式。每个基类都有一个 v 表,这正是 COM 所需要的。CLR 不执行此操作,它不支持 MI,并且只有一个 v 表。接口方法被合并到基类的v表中。