.net 为什么标记为隐藏基类中实现的方法可以调用隐藏方法?

ajsxfq5m  于 2023-04-13  发布在  .NET
关注(0)|答案(2)|浏览(148)

我一直在阅读c#规范,遇到了一个我没有预料到的场景,希望有人能分享一些光。
我偶然发现了new关键字,用于在派生类中隐藏基类的成员,随后讨论了何时在virtual成员上使用new而不是override
我在IDE中添加了一个小代码示例,希望看到编译错误

public class BaseType
{
    public void method()
    {
        // do nothing
    }
}
public class DerivedType : BaseType
{
    public new void method()
    {
        base.method();
    }
}

但却发现这是法律的的c#。既然派生类已经隐藏了method()的存在,为什么我仍然被允许调用它?
干杯

bybem2ql

bybem2ql1#

DerivedType对继承DerivedType的类隐藏了方法,而不是对它自己。
注意,为了隐藏方法,类必须知道在它的父类中存在一个同名且参数相同的方法。因此,一个类在它自己的作用域中隐藏方法在逻辑上是不正确的。

6yjfywim

6yjfywim2#

不要把方法 hiding 和方法 overriding 混在一起,它们是两种完全不同的东西。
当隐藏一个方法时,只有在通过隐藏方法的类型访问该方法时才隐藏它:

public class Foo
{
    public string Blah() { return "Hi from Foo!"; }
}

public class DerivedFoo: Foo
{
    public new string Blah() { return "Hi from DerivedFoo!"; }
}

现在我们有以下行为:

void TestFoos()
{
    Foo foo = new Foo();
    DerivedFoo derivedFoo = new DerivedFoo();
    Foo derivedFooInDisguise = derivedFoo as Foo;

    Console.WriteLine(foo.Blah()); //Outputs "Hi from Foo!"
    Console.WriteLine(derivedFoo.Blah()); //Outputs "Hi from DerivedFoo!"
    Console.WriteLine(derivedFooInDisguise.Blah()); //Outputs "Hi from Foo!" 
}

注意,即使Blah被声明为virtual,这种行为也是一样的。有趣的是第三次调用。该方法通过Foo类型的对象调用。由于它不是虚调用,因此调用的是Foo.Blah(),而不是DerivedFoo.Blah()
现在这与 method overriding 完全不同,其中虚方法调用总是解析为对象的运行时类型,而不是您调用它的类型:

public class Foo
{
    public virtual string Blah() { return "Hi from Foo!"; }
}

public class DerivedFoo: Foo
{
    public override string Blah() { return "Hi from DerivedFoo!"; }
}

现在我们有以下行为:

void TestFoos()
{
    Foo foo = new Foo();
    DerivedFoo derivedFoo = new DerivedFoo();
    Foo derivedFooInDisguise = derivedFoo as Foo;

    Console.WriteLine(foo.Blah()); //Outputs "Hi from Foo!"
    Console.WriteLine(derivedFoo.Blah()); //Outputs "Hi from DerivedFoo!"
    Console.WriteLine(derivedFooInDisguise.Blah()); ////Outputs "Hi from DerivedFoo!"
}

相关问题