【问题标题】:Use new keyword in c# [duplicate]在c#中使用新关键字[重复]
【发布时间】:2021-07-11 13:35:22
【问题描述】:

我有两节课

class  A
{
     public virtual void Metod1()
     {
         Console.WriteLine("A.Method1");
     }
}

class B : A
{
    public new void  Metod1()
    {
        Console.WriteLine("B.Method1");
    }
}

然后我编写一些代码来声明这些类的实例,并调用它们的方法

     static void Main(string[] args)
    {
        A a = new B();
        a.Metod1();
        B b = new B();
        b.Metod1();
        Console.ReadKey();
    }

我给出了以下结果:

A.Method1
B.Method1

但是当我从 B 类的签名方法 1 中删除关键字 new 并运行 Main 方法时,我得到了相同的结果。 问题:方法签名中的new关键字只是为了更好的可读性吗?

编辑:在某些情况下我们不能没有新的关键字吗?

【问题讨论】:

  • 你必须在 B 类中使用 override 或 new 因为否则它会隐藏父元素的方法。默认是新的,所以如果你不放置新的,它不会给你任何错误并且运行良好..
  • 旁注:考虑“混淆代码的读者和用户”是“新”在这种情况下的主要用法。在某些情况下,使用它可能会提高可读性(即需要为一些不友好的基类派生类),但在大多数情况下,它只会让基类的方法何时被调用以及何时被派生更难理解。

标签: c# .net inheritance


【解决方案1】:

new 关键字让代码阅读者知道此方法将在其基中隐藏同名方法。即使你省略了它,编译器也会以同样的方式处理它,但会警告你。

由于您将方法声明为 virtual,因此在编译时会收到以下警告:

'B.Metod1()' 隐藏继承的成员'A.Metod1()'。要使当前成员覆盖该实现,请添加 override 关键字。否则添加新关键字。

但是,如果您通过删除 virtual 将声明更改为:

  • A 中没有 virtual 的声明

    class A {
        public void Metod1() {
            Console.WriteLine("A.Method1");
        }
    }
    
    class B: A {
        public void Metod1() {
            Console.WriteLine("B.Method1");
        }
    }
    

仍会编译,但警告消息是:

'B.Metod1()' 隐藏继承的成员'A.Metod1()'。如果有意隐藏,请使用新关键字。

以上两种方式,如下:

  • 测试代码

    var b=new B();
    b.Metod1();
    (b as A).Metod1();
    

将输出:

B.方法1 A.方法1

但是,如果你声明如下:

  • B中使用覆盖声明

    class A {
        public virtual void Metod1() {
            Console.WriteLine("A.Method1");
        }
    }
    
    class B: A {
        public override void Metod1() {
            Console.WriteLine("B.Method1");
        }
    }
    

那么输出将是:

B.方法1 B.方法1

这是因为基类的Method1 不仅隐藏,而且被派生类覆盖

不能只使用 new 的情况是,如果 Method1 是抽象类中的 abstract 方法:

  • 必须在派生类中使用覆盖的代码

    abstract class A {
        public abstract void Metod1();
    }
    
    class B: A {
        public override void Metod1() { // use `new` instead of `override` would not compile
            Console.WriteLine("B.Method1");
        }
    }
    

在这种情况下,您不能只使用 new,因为A 需要派生类覆盖Method1

【讨论】:

  • 没关系,但是问题:方法签名中的新关键字是否只是为了更好的可读性,是否存在我们不能没有新关键字的情况
  • 所以它实际上并没有改变任何行为——只是为了便于阅读??
【解决方案2】:

Knowing When to Use Override and New Keywords (C# Programming Guide)

在 C# 中,派生类中的方法可以与方法同名 在基类中。您可以使用指定方法如何交互 new 和 override 关键字。 override 修饰符扩展了基础 类方法,新修饰符将其隐藏

还有

使用 new 表示您知道该成员 它修改 隐藏从基础继承的成员 类

【讨论】:

  • 基类在派生的new 方法中还需要virtual 有什么影响吗?在我的测试中,在派生类上有new 与没有override 具有相同的行为 - 我错过了什么? hides it 是什么意思?
【解决方案3】:

是的,你是对的,这是为了在这种情况下更好的可读性。

但是仔细检查你应该有一个警告,在隐藏基本方法时不要使用 new。

您可以在此处阅读更多内容: http://msdn.microsoft.com/en-us/library/vstudio/435f1dw2.aspx

【讨论】:

  • 你写它是为了在这种情况下更好的可读性。但是有没有我们不能没有新关键字的情况
  • @cosset 是的,当它不用作修饰符时,即:Class1 C = new Class1() 或当您设置将警告视为错误时。
  • 在方法、字段的签名中是否存在不能没有新关键字的情况
  • @cosset 新关键字可以在泛型声明中用作运算符、修饰符和约束 - 只有当它用作修饰符时,才能以警告的代价省略,在其他情况下它在不改变代码行为的情况下不能省略。
猜你喜欢
  • 1970-01-01
  • 2010-12-18
  • 2011-06-16
  • 2011-10-10
  • 1970-01-01
  • 1970-01-01
  • 2018-11-13
  • 1970-01-01
相关资源
最近更新 更多