为什么标记为隐藏基类中的实现的方法会调用隐藏方法?

时间:2014-08-18 11:50:58

标签: c# .net inheritance method-hiding

我已经围绕c#规范进行了一些阅读,并遇到了一个我没想到的情景,希望有人可以分享一些亮点。

我偶然发现new关键字隐藏了派生类中基类的成员,随后又讨论了何时使用new而不是override上的virtual public class BaseType { public void method() { // do nothing } } public class DerivedType : BaseType { public new void method() { base.method(); } } 成员。

我向我的IDE中输入了一些代码示例,希望看到编译错误

method()

但是发现这是合法的c#。由于派生类隐藏了{{1}}的存在,为什么我仍然可以调用它?

干杯

2 个答案:

答案 0 :(得分:1)

DerivedType隐藏了将继承DerivedType的类的方法,而不是自己的方法。
注意,为了隐藏方法,类必须知道在其父类中存在具有相同名称和相同参数的方法。因此,将方法隐藏在其自身范围内的一个类是不合逻辑的。

答案 1 :(得分:1)

请勿将方法隐藏与方法重写混合使用。他们是两个完全不同的野兽。

隐藏方法时,只有在通过隐藏方法开头的类型访问方法时才隐藏它:

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

现在这与方法重写完全不同,其中虚方法调用始终解析为对象的运行时类型,而不是您调用它的类型:

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!"
}