2013-04-04 73 views
6

我有两个类使用C#中的新关键字

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的签名method1中删除关键字new并运行Main方法时,我得到了相同的结果。 问题:为了更好的可读性,方法签名中是否有新关键字?

编辑:有没有我们不能没有新关键字的情况?

+0

你必须使用替代或新的B类bacause否则隐藏父元素的方法..默认是新的,所以如果它给你不,你不会将新错误和运行良好.. – 2013-04-04 06:44:14

+0

注意:在这种情况下,考虑“将代码的读者和用户混淆”作为“新”的主要用法。有些情况下使用它可能会提高可读性(即需要为一些不友好的基类推导类),但在大多数情况下,只会更难理解何时调用基类的方法以及何时派生基类。 – 2013-04-04 06:52:08

回答

3

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

但仔细检查你应该在隐藏基本方法时不要使用新的警告。

你可以在这里阅读更多: http://msdn.microsoft.com/en-us/library/vstudio/435f1dw2.aspx

+0

你写的是为了在这种情况下更好的可读性。但是有没有我们不能没有新关键字的情况 – cosset 2013-04-04 06:44:12

+0

@cosset是的,当它不被用作修饰语时,即:Class1 C = new Class1()您设置为将警告视为错误。 – 2013-04-04 06:59:23

+0

是否有情况,我们不能在方法,字段的签名中没有新的关键字 – cosset 2013-04-04 07:00:56

6

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

在C#,在派生类的方法可以有相同的名称作为在基类的方法 。您可以通过使用 新的和覆盖关键字来指定方法的交互方式。覆盖修饰符扩展了基类 类方法,新修饰符隐藏了

通过使用新的,你声称大家都知道,它修改成员 隐藏了从基类 继承的成员。

+0

基类是否还需要'virtual'中的'new'来派生出来有什么影响?在我的测试中,派生类拥有'new'具有与“override”相同的行为 - 我错过了什么?什么是“隐藏它”? – mmcrae 2015-06-22 22:11:19

7

关键字让读码器要知道,这种方法会隐藏在它的底部的同名方法。即使你忽略了它,编译器也会以同样的方式处理它,但是要警告你。

既然你声明的方法虚拟,你会得到当你编译这样的警告:

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

但是,如果通过删除更改声明虚拟为:

  • 宣言没有虚拟A

    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.Method1 
A.Method1 

但是,如果你声明为以下G:

  • 宣言与倍率B

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

那么输出将是:

 
B.Method1 
B.Method1 

这是因为Method1基类的不只是隐藏,但覆盖由派生类。

,你不能只使用的情况是,如果Method1抽象方法在抽象类:

  • 代码必须在派生类

    使用覆盖
    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"); 
        } 
    } 
    

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

+0

没关系,但问题是:为了更好的可读性,是否在方法签名中使用了新关键字?是否有些情况下我们不能没有新关键字 – cosset 2013-04-04 06:47:52

+0

,因此它实际上并没有改变任何行为 - 这仅仅是为了可读性? – mmcrae 2015-06-22 22:12:00