-
06-07-2019 - |
题
假设我有以下代码:
interface ISomeInterface
{
void DoSomething();
void A();
void B();
}
public abstract class ASomeAbstractImpl : ISomeInterface
{
public abstract void A();
public abstract void B();
public void DoSomething()
{
// code here
}
}
public class SomeImpl : ASomeAbstractImpl
{
public override void A()
{
// code
}
public override void B()
{
// code
}
}
问题是我希望将 ASomeAbstractImpl.DoSomething()
方法密封(最终),这样其他类就无法实现它。
由于代码现在是,SomeImpl
可以有一个名为 DoSomething()
的方法,并且可以调用它(它不会覆盖抽象类中具有相同名称的方法,因为这没有标记为虚拟),但我想切断在 SomeImpl
类中实现这种方法的可能性。
这可能吗?
解决方案
默认情况下,C#中的方法是密封的。但是,无法做任何事情以防止方法隐藏(在派生类中公开具有相同名称的方法,通常使用 new
)。
或者,就此而言,接口重新实现:
static void Main()
{
ISomeInterface si = new EvilClass();
si.DoSomething(); // mwahahah
}
public class EvilClass : ASomeAbstractImpl, ISomeInterface
{
public override void A() {}
public override void B() { }
void ISomeInterface.DoSomething()
{
Console.WriteLine("mwahahah");
}
}
其他提示
默认情况下,所有方法都是密封的,但是无法阻止成员隐藏。
C#编译器会在您隐藏成员时发出编译器警告,但除此之外,您无法阻止它。
默认情况下,未标记为虚拟的方法已被密封。在派生类中,您必须标记“覆盖”类。使用关键字 new 的方法,否则您将收到编译器警告。 如果超类的方法标记为虚拟,则可以按密封覆盖进行密封。
如果SomeImpl类包含DoSemthing方法,这意味着它隐藏了原始方法而不是覆盖。
在处理接口和抽象类时,更多的是关于你必须做什么,而不是你不能做什么。因此,您可以让界面用户知道这些是他们必须实现的方法,并且您可以使用虚拟关键字让您知道可以覆盖方法的抽象类。但是你不能阻止他们做太多。即使您故意不使用虚拟关键字,他们仍然可以使用新关键字隐藏它。
不隶属于 StackOverflow