Protecting against null events

D

dvestal

This question is a followup to my question here:

http://groups.google.com/group/micr...d71f033a6d2/07c99e4742fe5fdb#07c99e4742fe5fdb

I've been reading
http://www.yoda.arachsys.com/csharp/threads/lockchoice.shtml, and have
gotten a lot of great information from that page in general. So based
on what I've learned, I want to create a class that encapsulates the
safe use of an event, and I came up with the class at the end of this
post.

But it's not quite satisfying. I'd like to make it's strongly typed at
compile-time, and I don't know of a way to do that.

I first tried making it a generic class, with the type constrained to
be a delegate. That's when I learned that C# doesn't allow you to
constrain on a generic class based on the delegate type (compiler error
CS0702). So now I do type-checking at run-time, and clients can't see
the expected type via intellisense. Is there a better way?

It would also be nice if clients could add themselves to the handler
list using event-like syntax (i.e., the += operator), but it doesn't
seem that I'm allowed to override that operator. Am I missing
something?

Thanks for the excellent replies to the original question. Here's the
class as it exists now:

using System;

// The SafeEvent class is to ease the burden of using events in a
// thread-safe manner, which is surprisingly difficult.
// This code is adapted from the following webpage:
// http://www.yoda.arachsys.com/csharp/threads/lockchoice.shtml
public class SafeEvent
{
private object m_eventLock;
private Delegate m_event;
private Type m_eventType;

public SafeEvent(Type t)
{
if(!(t is Delegate))
{
throw new ArgumentException(
"SafeEvent requires a delegate type argument");
}

m_eventType = t;
m_eventLock = new object();
m_event = null;
}

public void Invoke(object[] args)
{
Delegate d;
lock(m_eventLock)
{
d = m_event;
}
if(d != null)
{
d.DynamicInvoke(args);
}
}

public void AddHandler(Delegate handler)
{
if(handler.GetType() != m_eventType)
{
throw new ArgumentException(
"Expected handler of type "
+ m_eventType.ToString());
}

lock(m_eventLock)
{
m_event = Delegate.Combine(m_event, handler);
}
}

public void RemoveHandler(Delegate handler)
{
if(handler.GetType() != m_eventType)
{
throw new ArgumentException(
"Expected handler of type "
+ m_eventType.ToString());
}

lock(m_eventLock)
{
m_event = Delegate.Remove(m_event, handler);
}
}
}
 
D

dvestal

Sorry, missed a compiler warning before I posted the code. please
ignore this clause from the class constructor:
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top