【问题标题】:Using the new keyword when creating a method with the same signature as one in the superclass?在创建与超类中具有相同签名的方法时使用 new 关键字?
【发布时间】:2016-02-09 17:38:47
【问题描述】:

很快回到 CS101。我正在尝试在类ConcurrentDictionary 中扩展方法Add 的行为。由于它不是virtualabstract,我不必用override 关键字标记它,我可以简单地在我的子类中创建一个具有相同签名的新函数。

虽然当我这样做时,我注意到一条视觉工作室消息说

如果要隐藏,请使用新关键字。

当从子类的实例调用时,使用这个关键字会改变方法的执行方式吗?

例如在下面的代码中,如果我有一个 MyClassEx 类的实例并且我调用 Method1 那么超类中的 Method1 将不会被正确调用(只有当我自己调用它时base)?。对于同样的实例,如果我调用Method2 会发生同样的结果,只有子类的Method2 会执行?

public class MyClass
{
    public void Method1() { Console.Out.WriteLine("MyClass.Method1"); }
    public void Method2() { Console.Out.WriteLine("MyClass.Method2"); }
}

public class MyClassEx : MyClass
{
    public void Method1()
    {
        Console.Out.WriteLine("MyClassEx.Method1");
        //base.Method1();
    }

    public new void Method2()
    {
        Console.Out.WriteLine("MyClassEx.Method2");
        //base.Method2();
    }
}

以这种方式使用new关键字只是“良好的编码”还是有一些效果?

编辑:看起来这只是“良好的编码”。虽然它引起了轻微的担忧。我希望在子类中创建一个新的Add 方法来改变ConcurrentDictionary 方法的行为。尽管从链接的答案看来,另一个编码员可以通过简单地引用超类的子类来绕过我的新实现。

MyClassEx mycex = new MyClassEx();
((MyClass)mycex).Method2();

在这种情况下,他们可以调用超类的Method2(默认行为)而忽略我已经实现的行为?

【问题讨论】:

标签: c# overriding method-hiding


【解决方案1】:

基于this,它只是“好的编码”。它将抑制您将获得的“隐藏”方法的警告,但不应更改函数的工作方式。

【讨论】:

  • 我对我的问题做了一个小小的修改,您是否愿意看一下?
  • 你的假设是正确的。编码人员可以通过将子类转换为超类来访问超类中定义的Method2。这是多态性的原则,也是语言所允许的。
【解决方案2】:

基本上,“new”关键字强制编译器/运行时将分配给 value/actor 别名的肉体视为,顾名思义:new。想想一个新引入的可选关键字“old”或“inherited”来标记相反的内容。

假设,A 类定义了一个值为 42 的值别名 a。让我们进一步假设,B 类继承自 A 类。没有任何关键字,但请记住可见性,B 将响应“c = B.a”并分配 42到 c.现在,让我们假设,类 C 也继承自类 A,但使用“new”关键字覆盖 a 的值别名并定义“a = 666;”在它的构造函数中。第三,类 D 再次继承自类 A,并定义“a = 999;”。

现在,继承类 B (BB)、C (CC)、D (DD),并分别询问 a 的值。试试看!

“新”事物是新事物,不会继承。使用“virtual”、“override”等来模仿 C++ 行为。

但请记住,继承通常是一件坏事。 C# 不支持合并继承是有原因的。 (B:A;C:A;D:B,C)

【讨论】:

    猜你喜欢
    • 2014-10-04
    • 1970-01-01
    • 1970-01-01
    • 2012-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-16
    相关资源
    最近更新 更多