あなたはそれをそのようにすることはできません。Subscription<Action<int>>
をと同じリストに入れることはできませんSubscription<Action<string, Foo>>
。
次のようなインターフェイスを作成し、それらを3番目のクラスに保存することをお勧めします。
interface IActionExecutor
{
bool CanExecuteForParameters(params object[] parameters);
void Execute(params object[] parameters);
}
// Implementation for one parameter
// You need to create one class per additional parameter.
// This is similar to the Action delegates in the framework.
// You can probably extract a base class here that implements
// some of the repetitive pars
public class ActionExecutor<in T> : IActionExecutor
{
private Action<T> _action;
public ActionExecutor(Action<T> action)
{
if(action == null) throw new ArgumentNullException("action");
_action = action;
}
public bool CanExecuteForParameters(params object[] parameters)
{
if(parameters == null) throw new ArgumentNullException("action");
if(parameters.Length != 1) return false;
return parameters[0] is T;
}
public void Execute(params object[] parameters)
{
if(parameters == null) throw new ArgumentNullException("action");
if(parameters.Length != 1)
throw new ArgumentOutOfRangeException("action");
_action((T)parameters[0]);
}
}
3番目のクラスには、次のリストがありますIActionExecutor
。
List<IActionExecutor> _subscriptions;
そして、あなたはそれをこのように使うでしょう:
public void Execute(params object[] parameters)
{
var matchingSubscriptions =
_subscriptions.Where(x => x.CanExecuteForParameters(parameters);
foreach(var subscription in matchingSubscriptions)
subscription.Execute(parameters);
}
これらのActionExecutorインスタンスの作成を簡素化するために、ファクトリクラスを提供できます。
public static class ActionExecutor
{
public IActionExecutor Create(Action action)
{
return new ActionExecutor(action);
}
public IActionExecutor Create<T>(Action<T> action)
{
return new ActionExecutor<T>(action);
}
public IActionExecutor Create<T1, T2>(Action<T1, T2> action)
{
return new ActionExecutor<T1, T2>(action);
}
// ... and so on
}
使用法は次のようになります。
_subscriptions.Add(ActionExecutor.Create(a));
_subscriptions.Add(ActionExecutor.Create(b));
_subscriptions.Add(ActionExecutor.Create(c));