可变数量的参数

时间:2011-11-18 03:40:47

标签: c# generics delegates messaging

我正在为我的项目改进现有的消息传递系统,它应该接受可变数量的参数。现在,泛型用于将参数传递给系统。很多代码都会重复,所以问题是 - 是否可以将具有不同数量参数的类的所有版本合并为一个单独的类? 我作为我的基础的整个消息传递系统可以在这里找到:CSharpMessenger

代码摘录:

public delegate void Callback();
public delegate void Callback<T>(T arg1);
public delegate void Callback<T, U>(T arg1, U arg2);

没有参数的版本:

static public class Messenger
{
    private static Dictionary<string, Delegate> eventTable = new Dictionary<string, Delegate>();

    static public void AddListener(string eventType, Callback handler)
    {
        if (!eventTable.ContainsKey(eventType))
        {
            eventTable.Add(eventType, null);
        }
        // Add the handler to the event.
        eventTable[eventType] = (Callback)eventTable[eventType] + handler;
    }

    static public void Invoke(string eventType)
    {
        Delegate d;
        if (eventTable.TryGetValue(eventType, out d))
        {
            Callback callback = (Callback) d;
            if (callback != null)
            {
                callback();
            }
        }
    }
}

带有一个参数的版本:

static public class Messenger<T>
{
    private static Dictionary<string, Delegate> eventTable = new Dictionary<string, Delegate>();

    static public void AddListener(string eventType, Callback<T> handler)
    {
        if (!eventTable.ContainsKey(eventType))
        {
            eventTable.Add(eventType, null);
        }
        // Add the handler to the event.
        eventTable[eventType] = (Callback<T>)eventTable[eventType] + handler;
    }

    static public void Invoke(string eventType, T arg1)
    {
        Delegate d;
        if (eventTable.TryGetValue(eventType, out d))
        {
            Callback<T> callback = (Callback<T>) d;
            if (callback != null)
            {
                callback(arg1);
            }
        }
    }
}

包含两个参数的版本:

static public class Messenger<T, U>
{
    private static Dictionary<string, Delegate> eventTable = new Dictionary<string, Delegate>();

    static public void AddListener(string eventType, Callback<T, U> handler)
    {
        if (!eventTable.ContainsKey(eventType))
        {
            eventTable.Add(eventType, null);
        }
        // Add the handler to the event.
        eventTable[eventType] = (Callback<T, U>)eventTable[eventType] + handler;
    }

    static public void Invoke(string eventType, T arg1, U arg2)
    {
        Delegate d;
        if (eventTable.TryGetValue(eventType, out d))
        {
            Callback<T, U> callback = (Callback<T, U>) d;
            if (callback != null)
            {
                callback(arg1, arg2);
            }
        }
    }
}

正如您所看到的,大多数代码都会自行重复,是否可以创建同一类的某些通用版本,这将采用可变数量的参数并避免重复相同的代码多次?

感谢。

1 个答案:

答案 0 :(得分:2)

回调参数通常在EventArgs的子类中传递。已经有一个简单的通用委托来抽象:EventHandler<TEventArgs> where TEventArgs : EventArgs。参数的可变性可以添加到EventArgs的子类中。

因此,如果您可以重构代码以使用这些类,那么您只能拥有一个版本。像这样:

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

  public static void AddListener(string eventType, EventHandler<TEventArgs> handler) {
    if (eventTable.ContainsKey(eventType)) {
      eventTable[eventType] = eventTable[eventType] + handler;
    }
    else {
      eventTable.Add(eventType, handler);
    }
  }

  public static void Invoke(string eventType, TEventArgs args) {
    EventHandler<TEventArgs> d;
    if (eventTable.TryGetValue(eventType, out d)) {
      if (d != null) {
        d(args);
      }
    }
  }
}