I often see code like that which is shown here, ie where an object is allocated and then used as a “lock object”.
It seems to me that you could use any object for this, including the event itself as the lock object. Why allocate a new object that does nothing? My understanding is that calling lock() on an object doesn’t actually alter the object itself, nor does it actually lock it from being used, it’s simply used as a placeholder for multiple lock statements to anchor on.
public class Shape : IDrawingObject, IShape
{
// Create an event for each interface event
event EventHandler PreDrawEvent;
event EventHandler PostDrawEvent;
object objectLock = new Object();
// Explicit interface implementation required.
// Associate IDrawingObject's event with
// PreDrawEvent
event EventHandler IDrawingObject.OnDraw
{
add
{
lock (objectLock)
{
PreDrawEvent += value;
}
}
remove
{
lock (objectLock)
{
PreDrawEvent -= value;
}
}
}
}
So my question is, is this really a good thing to do?
No, you can’t do that. An “event” is actually just some accessor methods. Assuming you mean the backing delegate, that would be very bad – delegates are immutable: every time you add/remove a subscriber, you get a different delegate.
Actually, the 4.0 compiler now does this with lock-free code using
Interlocked– it may be worth following this approach instead.In your example, the
objectLockensures that all callers (to that instance) are locking against the same object, which is important – but without the ugliness of locking onthis(which is how the C# compiler used to work).—
Update: your example shows code that is necessary before C# 4.0, access to a field-like-event inside the type talked directly to the field: the normal field-like-event locking was not respected. This was changed in C# 4.0; you can now (in C# 4.0) safely re-write this as:
All the correct behaviour is then followed.