不,你不能覆盖静态方法。 “static”也意味着它是由编译器静态绑定的,因此在运行时找不到要调用的实际方法,但在编译时绑定。
你应该做的是使类非静态。使方法成为虚拟并覆盖它并充分利用实际继承。然后,如果您真的需要它,请为您的类的引用创建一个静态入口点。例如一个静态工厂,单例(在大多数情况下它是一个反模式但是和静态类一样好)或者只是一个静态属性。
好的,这就是我所做的
public abstract class Base<T> where T : Base<T>, new() { #region Singleton Instance //This is to mimic static implementation of non instance specific methods private static object lockobj = new Object(); private static T _Instance; public static T Instance { get { if (_Instance == null) { lock (lockobj) { if (_Instance == null) { _Instance = new T(); } } } return _Instance; } } #endregion //Singleton Instance #region Abstract Definitions public abstract T GetByID(long id); public abstract T Fill(SqlDataReader sr); #endregion //Abstract Definitions } public class InstanceClass : Base<InstanceClass> { //empty constructor to ensure you just get the method definitions without any //additional code executing public InstanceClass() { } #region Base Methods public override InstanceClass GetByID(long id) { SqlDataReader sr = DA.GetData("select * from table"); return InstanceClass.Instance.Fill(sr); } internal override InstanceClass Fill(SqlDataReader sr) { InstanceClass returnVal = new InstanceClass(); returnVal.property = sr["column1"]; return returnVal; } }
我认为,如果不打破太多纯粹的OO原则,这将是您想要做的可行解决方案。
如果你想做抽象静态方法,那么这是有效的,并且结果是我最容易适应的解决方案:
class TestBase<ChildType> where ChildType : TestBase<ChildType> { //public static abstract void TargetMethod(); public static void Operation() { typeof(ChildType).GetMethod("TargetMethod").Invoke(null, null); } } class TestChild : TestBase<TestChild> { public static void TargetMethod() { Console.WriteLine("Child class"); } }
但我仍然将Stafan标记为解决方案,因为使用实例继承可能是类似情况下任何人的最佳建议。但我只需要为它重写太多代码。
您可以将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"); }); } }
因为这些是静态实例,但是 - _targetMethod 在所有实例中共享 - 更改它 TestChild 改变它 TestBase 同样。你可能会或可能不会关心这一点。如果你这样做,仿制药或者 Dictionary<Type, Action> 可能有帮助。
_targetMethod
TestChild
TestBase
Dictionary<Type, Action>
但总的来说,如果你不坚持静态,或者使用组合而不是继承,那么你会有更轻松的时间。