基类可以确定派生类是否覆盖了虚拟成员吗?

这是我class级的简化版本:

public abstract class Task { private static object LockObject = new object(); protected virtual void UpdateSharedData() { } protected virtual void UpdateNonSharedData() { } public void Method() { lock(LockObject) { UpdateSharedData(); } UpdateNonSharedData(); } } 

我试图隐藏派生类的锁定代码。 但是,如果派生类重写UpdateSharedData,我只想获取锁; 如果没有,我不希望该方法在更新非共享数据之前阻止并等待所有其他正在更新共享数据的正在运行的实例。

所以对于Method来说(看似)显而易见的事情是检查并查看当前实例的UpdateSharedData实现是否覆盖了基类的实现。 我很确定如果不使用reflection这是不可能的,并且可能不希望这样做。

我已经想到了一些解决方法,但它们都很尴尬:

  • 添加派生类的构造函数设置的受保护bool属性,并检查该属性以查看是否需要锁定。 这在隐藏派生类中的锁定代码方面做得非常糟糕。
  • 使UpdateSharedData方法成为委托属性,让任何派生类在其构造函数中将属性设置为私有方法,并且只有在委托不为空时才获取锁。 那更好,但它仍然很糟糕。

如果您定义了一个抽象Task和一个IHasSharedData接口,那么在Method中检查派生的Task是否在执行锁之前实现了IHasSharedData。 只有实现接口的类才需要等待。 我意识到这可以避免回答实际问题,但我认为这比使用reflection更清晰。 希望你能找到一个更好的界面名称,它更接近于类实际做的。

 public interface IHasSharedData { void UpdateSharedData(); } public abstract class Task { private static object LockObject = new object(); protected virtual void UpdateNonSharedData() { } public void Method() { if (this is IHasSharedData) { lock(LockObject) { UpdateSharedData(); } } UpdateNonSharedData(); } } public class SharedDataTask : Task, IHasSharedData { public void UpdateSharedData() { ... } } 

你可以用reflection的微笑来检查:

 bool IsUpdateSharedDataOverridden() { Type t = this.GetType(); MethodInfo m = subType.GetMethod("UpdateSharedData"); return m.DeclaringType == t && m.GetBaseDefinition().DeclaringType == typeof(Task); } 

实际上,你在谈论两个不同的对象:

 public abstract class Task { protected virtual void UpdateNonSharedData() { } public virtual void Method() { UpdateNonSharedData(); } } public abstract class TaskWithSharedData : Task { private static object LockObject = new object(); protected virtual void UpdateSharedData() { } public overrides void Method() { lock(LockObject) { UpdateSharedData(); } base.Method(); } } 

但是,更理想的解决方案将是战略模式。