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:
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()
{
...
}
}
You can do this check with a smidge of reflection:
bool IsUpdateSharedDataOverridden()
{
Type t = this.GetType();
MethodInfo m = subType.GetMethod("UpdateSharedData");
return m.DeclaringType == t && m.GetBaseDefinition().DeclaringType == typeof(Task);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With