基类可以确定派生类是否重写了虚拟成员吗?
这是我的类的简化版本:
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 时才获取锁。 这样好多了,但还是有点糟糕。
Here's a simplified version of my 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();
}
}
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.
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:
- 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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您定义了一个抽象任务和一个 IHasSharedData 接口,那么在方法中您在执行锁定之前检查派生任务是否实现了 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.
您可以通过一些反思来进行此检查:
You can do this check with a smidge of reflection:
实际上,您正在谈论两个不同的对象:
但是,更理想的解决方案是策略模式。
Actually, you are talking about two different objects:
But, more ideal solution will be the Strategy Pattern.