I'm trying to implement EventArgs to pass a list of parameters to my messaging system: Question.

I subclassed EventArgs:

public class SingleParameterArgs<T> : EventArgs
{
    public T arg1;

    public SingleParameterArgs(T _arg1)
    {
        arg1 = _arg1;
    }
}

Here's the class and method that should accept the EventArgs:

static public class Messenger<TEventArgs> where TEventArgs : EventArgs {
    private static Dictionary< string, EventHandler<TEventArgs> > eventTable = new Dictionary< string, EventHandler<TEventArgs> >();

    static public void Invoke(string eventType, TEventArgs args) {
        EventHandler<TEventArgs> eventHandler;

        if (eventTable.TryGetValue(eventType, out eventHandler)) {          
            if (eventHandler != null)
                eventHandler();
        }
    }

}

Before implementing EventArgs I would invoke a message in the following way:

Messenger<GameEndingType>.Invoke( "end game", GameEndingType.TimeEnded );

But now it looks much longer and much more complicated:

Messenger< SingleParameterArgs<GameEndingType> >.Invoke( "end game", new SingleParameterArgs<GameEndingType>(GameEndingType.TimeEnded) );

Is it possible to make it look shorter? I don't want to type such a long line every time I need to send a message. Maybe I could create a wrapper? Something like this would be perfect: Messenger.Invoke("end game", GameEndingType.TimeEnded);

What is the best way to create a uniform wrapper for a random amount of parameters?

有帮助吗?

解决方案

Are you happy for your Messenger class to be tied to SingleParameterArgs<T>? If so, you could use:

// Here TEventArgs represents the element type *within* SingleParameterArgs
public static class Messenger<TEventArgs> {
    private static
        Dictionary<string, EventHandler<SingleParameterArgs<TEventArgs>> eventTable = 
            new Dictionary<string, EventHandler<SingleParameterArgs<TEventArgs>>();

    public static void Invoke(string eventType, TEventArgs args) {
        EventHandler<SingleParameterArgs<TEventArgs>> eventHandler;

        if (eventTable.TryGetValue(eventType, out eventHandler)) {          
            if (eventHandler != null) {
                eventHandler();
            }
        }
    }
}

Of course you can have both, with a totally general Messenger class (as per your question), and then a SingleParameterMessenger class which delegates to it:

public static class SingleParameterMessenger<TEventArgs> {
    public static void Invoke(string eventType, TEventArgs args) {
        Messenger<SingleParameterArgs<TEventArgs>>.Invoke(eventType, args);
    }
}

Just as an aside, I'm not really sure this is all a good idea anyway - particularly in terms of static registration, which tends to make testing harder, and certainly needs more care in terms of concurrency. (Your code is currently not threadsafe.)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top