防止方法在 C# 中被覆盖
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9914908/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Preventing a method from being overridden in C#
提问by nighthawk457
How do I prevent a method from being overridden in a derived class?
如何防止在派生类中重写方法?
In Java I could do this by using the finalmodifier on the method I wish to prevent from being overridden.
在 Java 中,我可以通过final在我希望防止被覆盖的方法上使用修饰符来做到这一点。
How do I achieve the same in C#?
I am aware of using sealedbut apparently I can use it only with the overridekeyword?
我如何在 C# 中实现相同的目标?
我知道使用sealed但显然我只能将它与override关键字一起使用?
class A
{
public void methodA()
{
// Code.
}
public virtual void methodB()
{
// Code.
}
}
class B : A
{
sealed override public void methodB()
{
// Code.
}
}
So in the above example I can prevent the methodB()from being overridden by any classes deriving from class B, but how do I prevent class Bfrom overriding the methodB()in the first place?
因此,在上面的示例中,我可以防止methodB()从 class 派生的任何类覆盖 the B,但是首先如何防止 classB覆盖 the methodB()?
Update: I missed the virtualkeyword in the methodB()declaration on class A when i posted this question. Corrected it.
更新:当我发布这个问题时,我错过了A 类声明中的virtual关键字methodB()。纠正了它。
采纳答案by Kendall Frey
You don't need to do anything. The virtualmodifier specifies that a method can be overridden. Omitting it means that the method is 'final'.
你不需要做任何事情。所述virtual修饰符指定的是,方法可以被覆盖。省略它意味着该方法是“最终的”。
Specifically, a method must be virtual, abstract, or overridefor it to be overridden.
具体来说,一个方法必须是virtual、abstract或override才能被覆盖。
Using the newkeyword will allow the base class method to be hidden, but it will still not override it i.e. when you call A.methodB()you will get the base class version, but if you call B.methodB()you will get the new version.
使用new关键字将允许隐藏基类方法,但它仍然不会覆盖它,即当您调用时,A.methodB()您将获得基类版本,但如果您调用,B.methodB()您将获得新版本。
回答by Shyju
As you mentioned, you can prevent further overriding of MethodB in class B by using sealedwithoverride
正如您所提到的,您可以通过使用with来防止进一步覆盖 B 类中的 MethodBsealedoverride
class B : A
{
public sealed override void methodB()
{
Console.WriteLine("Class C cannot override this method now");
}
}
Use of the sealedmodifier along withoverrideprevents a derived class from further overriding the method.
与sealed修饰符一起使用override可防止派生类进一步覆盖该方法。
If you do not want methodBin class A to be overridden by any child classes, do not mark that method virtual. Simply remove it. virtual keyword enable the method to be overridden in child classes
如果您不想methodB在 A 类中被任何子类覆盖,请不要标记该方法virtual。只需将其删除。virtual 关键字使该方法能够在子类中被覆盖
public void methodA()
{
}
Use sealedkeyword on your classes to prevent further overriding of the class
sealed在您的类上使用关键字以防止进一步覆盖该类
回答by psubsee2003
In a base class, the sealed keyword is only used to prevent a class from being derived, but in inherited classes it can be used to prevent another inherited class from overriding the method.
在基类中,sealed 关键字仅用于防止类被派生,但在继承类中,它可用于防止另一个继承类覆盖该方法。
To prevent a base class method from being overridden, just do not specify it as virtual. In the example you provided, class B could not override methodBbecause methodBwas not marked as virtual on the original class.
为了防止基类方法被覆盖,只需不要将其指定为虚拟的。在您提供的示例中,B 类无法覆盖,methodB因为methodB在原始类上未标记为虚拟。
this will compile:
这将编译:
class A
{
public virtual void methodA()
{
//code
}
public virtual void methodB()
{
//code
}
}
class B:A
{
public override void methodB()
{
//code
}
}
this will not:
这不会:
class A
{
public void methodA()
{
//code
}
public void methodB()
{
//code
}
}
class B:A
{
public override void methodB()
{
//code
}
}
EDITTED: clarified and corrected my original statement about the sealed keyword
编辑:澄清并更正了我关于密封关键字的原始声明
回答by KeithS
In C#, a function not marked virtual(which also includes overrides of virtual functions) is effectively sealed and cannot be overridden. So, your example code actually won't compile because the override keyword is not valid unless there is a method marked virtual with the same signature in a base class.
在 C# 中,未标记的函数virtual(也包括虚函数的覆盖)是有效密封的,不能被覆盖。因此,您的示例代码实际上无法编译,因为 override 关键字无效,除非在基类中存在具有相同签名的标记为 virtual 的方法。
If A.methodB() were marked virtual, then you could override the method from A, but prevent it being further overridden in classes deriving more indirectly, using the sealedkeyword exactly as you have shown.
如果 A.methodB() 被标记为虚拟,那么您可以从 A 覆盖该方法,但防止它在更间接地派生的类中被进一步覆盖,sealed完全使用您显示的关键字。
One thing to keep in mind is that while method overriding can be prevented, method hidingcannot. Given your current definition of class A, the following definition of class B is legal and there's nothing you can do about it:
要记住的一件事是,虽然可以防止方法覆盖,但方法隐藏却不能。鉴于您当前对 A 类的定义,B 类的以下定义是合法的,您对此无能为力:
class B:A
{
public new void methodB()
{
//code
}
}
The newkeyword basically "breaks" the inheritance/overriding hierarchy as it pertains to this one method; any reference to a class B, treated as a class B (or any further derived type) will use the implementation from class B and ignore the one from class A unless B's implementation specifically calls back to it. However, if you were to treat an instance of class B as a class A (by casting it or passing it as a parameter), then the "new" implementation is ignored.
的new关键字基本上“场所”继承/覆盖分层结构,因为它涉及到这一个方法; 任何对类 B 的引用,被视为类 B(或任何进一步的派生类型)将使用类 B 的实现并忽略类 A 的实现,除非 B 的实现专门回调它。但是,如果您将类 B 的实例视为类 A(通过强制转换或将其作为参数传递),则忽略“新”实现。
This differs from overriding, where a class B that is being treated as a class A and truly overrides a virtual methodB would still use class B's override of the method. Also understand that method hiding is inferred (though you will get a compiler warning); if you declare a method with the same signature in a derived class and do not specify either new or override, the base class method will be hidden.
这与重写不同,在重写中,被视为类 A 并真正重写虚拟方法 B 的类 B 仍将使用类 B 对该方法的重写。还要了解方法隐藏是推断出来的(尽管您会收到编译器警告);如果在派生类中声明具有相同签名的方法并且未指定 new 或 override ,则基类方法将被隐藏。

