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.
您不能将方法同时声明为override
和new
。它们是相互排斥的。
【讨论】:
@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
,您应该使用new
。 protected
字段在其派生类中可见,如果声明具有相同名称的字段,您将隐藏它。
@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
方法被标记为 public
或 protected
,否则使用 virtual
修饰符无论如何都是毫无意义的,因为它不会对基类/其他类不可见。
【讨论】:
以上是关于C#中的新修饰符的主要内容,如果未能解决你的问题,请参考以下文章
在Java和c#中如果不写访问修饰符,类和类成员默认的是啥访问修饰符?