名称隐藏与覆盖

本文关键字:覆盖 隐藏 | 更新日期: 2023-09-27 18:34:13

什么时候会在覆盖关键字上实现名称隐藏?由于使用名称隐藏提供的功能可以使用覆盖关键字实现?

名称隐藏与覆盖

好吧,如果您需要覆盖virtual的成员.override关键字适用于virtualabstract成员。

如果是virtual成员,则更喜欢override而不是隐藏,因为当您override时,您仍然可以执行base

overridenew不是等价的,并且不提供相同的功能。

以这些类为例。

public class Herple
{
    public virtual void DoTheVirtualHerple()
    {
        Console.WriteLine("Virtual Herple!");
    }
    public void DoTheHerple()
    {
        Console.WriteLine("Herple!");
    }
}
public class Derple : Herple
{
    public override void DoTheVirtualHerple()
    {
        Console.WriteLine("Actually I'd prefer to Derple!");
    }
    public new void DoTheHerple()
    {
        Console.WriteLine("Let's Derple instead!");
    }
}

Derple实例分配给类型Herple变量时,调用具体方法的行为会根据该方法是被覆盖还是隐藏而变化。 例如:

var herpleList = new List<Herple> {new Herple(), new Derple()};
foreach (var curple in herpleList)
{
    curple.DoTheVirtualHerple();
    curple.DoTheHerple();
}

指纹:

Virtual Herple!
Herple!
实际上我更喜欢Derple!
Herple!

对于您最初的问题,至于您何时更喜欢名称隐藏而不是覆盖,一般来说您不喜欢它,但是如果您要从您不负责的 API 扩展类,这可能是您唯一的选择。但是,您应该知道,在使用基类的任何情况下都不会调用您的逻辑,并相应地进行规划,并验证您的设计是否确实正确。

如果你在基类中的方法不是virtualabstract那么你别无选择,只能隐藏它。还要记住,如果您不使用关键字new方法隐藏,您将收到警告。

新修饰符(C# 参考

您可以在不使用新修饰符的情况下隐藏成员,但结果是 警告。如果使用 new 显式隐藏成员,则修饰符 禁止显示此警告并记录派生的事实 版本旨在作为替换。

您可能还会看到:覆盖和新覆盖之间有什么区别? - 乔恩·斯基特

例如

public class A
{
    public virtual void Virtual()
    {
        Console.WriteLine("Virtual A");
    }
    public void NameHidding()
    {
        Console.WriteLine("Name Hidding A");
    }
}
public class B : A
{
    public override void Virtual()
    {
        Console.WriteLine("Override B");
    }
    public new void NameHidding()
    {
        Console.WriteLine("Name Hidding B");
    }
}

如果对象的数据类型为 B:

        B b = new B();
        b.Virtual();
        b.NameHidding();

指纹:
覆盖 B
姓名 隐藏 B

但是,如果我们将对象的数据类型定义为 A:

        A b = new B();
        b.Virtual();
        b.NameHidding();

指纹:
覆盖 B
姓名 隐藏 A

与多态性的关系。