我不确定在这里完全掌握了用例。似乎更灵活的解决方案将涉及到一些真正的数据发送序列化/反序列化,这将允许端到端的类型安全通信。
这是说,各位代表不要让你想直接做什么,你可以创建一个通用的方法来自动大部分的工作:
delegate void Callback(params object[] args);
static void Method1(params string[] args) { }
static Callback Wrap<T>(Action<T[]> action)
{
return (Callback)((object[] args) => action(args.Cast<T>().ToArray()));
}
static void Main(string[] args)
{
Callback callback1 = Wrap<string>(Method1);
}
这将铸就args
的每个元素数组到指定的类型。当然,这要求包装方法具有一个数组作为其唯一参数,例如,一个params
阵列。为了处理一些更喜欢你的具体的例子,你可以这样做:
static void Method2(string arg) { }
static Callback Wrap<T>(Action<T> action)
{
return (Callback)((object[] args) => action((T)args[0]));
}
static void Main(string[] args)
{
Callback callback2 = Wrap<string>(Method2);
}
由于与.NET泛型委托类型Action
和Func
,你就必须申报为每个参数数代表一个特定的包装方法。以上仅适用于一个参数。如果你有两个参数的例子,那么你需要添加:
static void Method3(string arg1, bool arg2) { }
static Callback Wrap<T1, T2>(Action<T1, T2> action)
{
return (Callback)((object[] args) => action((T1)args[0], (T2)args[1]));
}
static void Main(string[] args)
{
Callback callback3 = Wrap<string, bool>(Method3);
}
等。写这些小封装是否真的值得,当然取决于你使用它们的多少。我会说在第三次或第四次回调之后,你可能会觉得它值得。
当然,我仍然认为用基于序列化的方法可能会更好。但这是一个不同的问题。 :)
是的,如果你改变你的委托声明。 – MarcinJuraszek 2014-12-02 05:18:14
@MarcinJuraszek这将与任何方法? – Ben 2014-12-02 05:21:13
任何采用相同参数集并返回相同类型的方法。我真的不明白为什么你需要一个能够匹配一切的代表。你确定你在这里没有面临XY问题吗? – MarcinJuraszek 2014-12-02 05:21:42