静态继承就像实例继承一样工作.除非您不允许将静态方法设为虚拟或抽象.
class Program {
static void Main(string[] args) {
TestBase.TargetMethod();
TestChild.TargetMethod();
TestBase.Operation();
TestChild.Operation();
}
}
class TestBase {
public static void TargetMethod() {
Console.WriteLine("Base class");
}
public static void Operation() {
TargetMethod();
}
}
class TestChild : TestBase {
public static new void TargetMethod() {
Console.WriteLine("Child class");
}
}
Run Code Online (Sandbox Code Playgroud)
这将输出:
Base class
Child class
Base class
Base class
Run Code Online (Sandbox Code Playgroud)
但我想要:
Base class
Child class
Base class
Child class
Run Code Online (Sandbox Code Playgroud)
如果我可以在静态方法上,我会使TargetMethod虚拟,它会完成这项工作.但有没有可以达到同样的效果?
编辑:是的,我可以在子类中放置一个Operation副本,但这需要复制并将大量代码粘贴到每个子节点,在我的例子中大约是35个类,这是一个维护噩梦.
Ste*_*ger 13
不,你不能覆盖静态方法."static"也意味着它是由编译器静态绑定的,因此在运行时找不到要调用的实际方法,但在编译时绑定.
你应该做的是使类非静态.使方法成为虚拟并覆盖它并充分利用实际继承.然后,如果您确实需要它,请为您的类的引用创建一个静态入口点.例如一个静态工厂,单例(在大多数情况下它是一个反模式但是和静态类一样好)或者只是一个静态属性.
您可以将TargetMethod存储为委托,子类可以根据需要进行更改:
class TestBase {
protected static Action _targetMethod;
static new() {
_targetMethod = new Action(() => {
Console.WriteLine("Base class");
});
}
public static void TargetMethod() {
_targetMethod();
}
public static void Operation() {
TargetMethod();
}
}
class TestChild : TestBase {
static new() {
_targetMethod = new Action(() => {
Console.WriteLine("Child class");
});
}
}
Run Code Online (Sandbox Code Playgroud)
因为这些是静态实例,_targetMethod所以它们在所有实例之间共享 - 更改它TestChild也会改变它TestBase.你可能会或可能不会关心这一点.如果你这样做,泛型或者Dictionary<Type, Action>可能有所帮助.
但总的来说,如果你不坚持静态,或者使用组合而不是继承,那么你会有更轻松的时间.
| 归档时间: |
|
| 查看次数: |
13857 次 |
| 最近记录: |