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

这是我班级的简化版本:
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实现是否覆盖了基类的实现.我很确定如果不使用反射这是不可能的,并且可能不希望这样做.

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

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

解决方法

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

相关文章

目录简介使用JS互操作使用ClipLazor库创建项目使用方法简单测...
目录简介快速入门安装 NuGet 包实体类User数据库类DbFactory...
本文实现一个简单的配置类,原理比较简单,适用于一些小型项...
C#中Description特性主要用于枚举和属性,方法比较简单,记录...
[TOC] # 原理简介 本文参考[C#/WPF/WinForm/程序实现软件开机...
目录简介获取 HTML 文档解析 HTML 文档测试补充:使用 CSS 选...