我不確定在這裏完全掌握了用例。似乎更靈活的解決方案將涉及到一些真正的數據發送序列化/反序列化,這將允許端到端的類型安全通信。
這是說,各位代表不要讓你想直接做什麼,你可以創建一個通用的方法來自動大部分的工作:
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