基类可以确定派生类是否重写了虚拟成员吗? [英] Can a base class determine if a derived class has overridden a virtual member?

查看:146
本文介绍了基类可以确定派生类是否重写了虚拟成员吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我班的简化版本:

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时获取锁;如果没有,我不希望该方法阻塞并等待所有其他正在运行的实例来更新共享数据,然后再更新非共享数据.

I'm trying to hide the locking code from derived classes. But I only want to obtain the lock if the derived class overrides UpdateSharedData; if it doesn't, I don't want the method to block and wait on all of the other running instances that do update shared data before it updates the non-shared data.

因此,Method要做的(看似)显而易见的事情是检查并查看当前实例的UpdateSharedData实现是否已覆盖基类的实现.我很确定如果不使用反射就不可能做到这一点,并且这样做可能是不可取的.

So the (seemingly) obvious thing for Method to do is to check and see if the current instance's implementation of UpdateSharedData has overriden the base class's implementation. I'm pretty sure this isn't possible without using reflection, and it's probably not desirable to do that.

我已经想到了一些解决方法,但是它们都非常笨拙:

I've thought of some workarounds to this, but they're all pretty awkward:

  • 添加一个由派生类的构造函数设置的受保护的bool属性,并检查该属性以查看是否需要锁定.在隐藏派生类中的锁定代码方面做得非常糟糕.
  • 使UpdateSharedData方法具有委托属性,并设置任何派生类 该属性为其构造函数中的私有方法,并且只有在委托不为null时,才获得锁.更好,但是还是很烂.
  • Add a protected bool property that the derived class's constructor sets, and check that property to see if a lock is needed. That's doing a pretty terrible job of hiding the locking code from the derived classes.
  • Make the UpdateSharedData method a delegate property, have any derived class set the property to a private method in its constructor, and only obtain the lock if the delegate isn't null. That's better, but it still kind of sucks.

推荐答案

如果您定义了一个抽象Task和一个IHasSharedData接口,该怎么办,然后在Method中检查派生Task在执行锁定之前是否实现了IHasSharedData.仅实现接口的类需要等待.我意识到这避免了回答实际问题,但是我认为这比使用反射是一种更干净的解决方案.希望您会为该接口找到一个更好的名称,该名称与类的实际行为更紧密地匹配.

What if you defined an abstract Task and a IHasSharedData interface, then in Method you check if the derived Task implements IHasSharedData before doing the lock. Only classes that implement the interface need wait. I realize that this avoids answering the actual question, but I think it would be a cleaner solution than using reflection. Hopefully, you'd find a better name for the interface that more closely matches what the classes actually do.

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()
    {
       ...
    }
}

这篇关于基类可以确定派生类是否重写了虚拟成员吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆