C#中的新修饰符

Posted

技术标签:

【中文标题】C#中的新修饰符【英文标题】:new modifier in C# 【发布时间】:2009-12-17 15:33:33 【问题描述】:

MSDN 说:

当用作修饰符时,新的 关键字显式隐藏成员 从基类继承。当你 隐藏继承的成员,派生的 成员的版本替换 基类版本。虽然你可以 隐藏成员而不使用 new 修饰符,结果是警告。 如果您使用 new 显式隐藏 成员,它会抑制此警告并 证明派生的事实 版本旨在作为替代品。

例子:

class Base

 int value;

 virtual bool Foo()
 
   value++;
 


class Derived : Base

 int value;

 override bool Foo()
 
  value++;
 


我必须在 Derived.value 声明中添加 new 修饰符吗?有什么变化?

【问题讨论】:

NB - 我说的是 int 值或新的 int 值而不是 Foo() int 是“值类型”,因此不需要用“new”初始化。查找“值类型和引用类型”。希望有帮助 【参考方案1】:

由于value 字段为private,因此无法在派生类中访问它。因此,派生类中的声明并没有真正隐藏任何东西。您不应该在声明中添加new。如果你这样做了,什么都不会改变,除了编译器会警告你不正确地使用new。如果在派生类中可以访问value 字段(例如,它是public),那么您应该使用new 来表达您隐藏基成员的意图:

class A 
    public int field;

class B : A 
    public int field; // warning. `B.field` hides `A.field`. 

使用new 将使该警告静音(不会产生其他影响):

class B : A 
    public new int field; // Dear compiler, shut up please.

您不能将方法同时声明为overridenew。它们是相互排斥的。

【讨论】:

@Mehrdad 如果您举一个使用新修饰符的好地方的示例,这也可能会有所帮助(我会抛出一个......但我不想创建一个答案只是为了那个)。 所以即使我不使用'new'修饰符 Derived.Foo() 将始终访问 Derived.value? @漫画队长:是的。除非您像((Base)this).value 那样将其明确转换为基础。一般来说new对生成的代码没有影响;就在编译器警告上。【参考方案2】:

以您的示例为例,Derived.value 不是“隐藏”Base.value。 C# 的默认访问修饰符是 Private。如果您将 Base.value 设为 Public,那么是的,使用新的修饰符将删除警告。

【讨论】:

不是默认访问修饰符private吗? 默认访问修饰符是private,除了在namespace级别声明的类型,private没有意义,默认是internal ...顺便说一句,如果是protected,您应该使用newprotected 字段在其派生类中可见,如果声明具有相同名称的字段,您将隐藏它。 @Broam:啊,我认为你是对的。 vb.net 的默认值是受保护的。【参考方案3】:

new修饰符主要用于隐藏非虚方法。与 override 修饰符不同,它用于隐藏所有类成员,而不仅仅是方法(即变量和属性)。

主要目的是当您使用它来隐藏方法而不是使用覆盖时(顺便说一下,要隐藏方法,您不能同时使用覆盖和新方法。这会给您带来错误,而不仅仅是减弱)。

使用 virtual 和 override 修饰符将始终类似于使用 new 修饰符,只是当您使用 virtual 和 override 时,除了从 Child 类本身内部之外,您不能调用 Base 类

【讨论】:

【参考方案4】:

不,你不需要,因为在这种情况下,基方法被标记为virtual,因此基类打算覆盖此方法。

您可能需要使用new 修饰符的情况是基方法未标记为virtual,例如:

class Base

    int value;

    public void Foo()
    
        value++;
    


class Derived : Base

    int value;

    new public void Foo()
    
        value--;
    

另外,在您上面的示例中,我们必须假设基本 Foo 方法被标记为 publicprotected,否则使用 virtual 修饰符无论如何都是毫无意义的,因为它不会对基类/其他类不可见。

【讨论】:

以上是关于C#中的新修饰符的主要内容,如果未能解决你的问题,请参考以下文章

C# 中的sealed修饰符学习

c#类的修饰符都有哪些?

在Java和c#中如果不写访问修饰符,类和类成员默认的是啥访问修饰符?

C#语言中的修饰符汇总

在Java和c#中如果不写访问修饰符,类和类成员默认的是啥访问修饰符?

C#中的默认访问修饰符