在寫delegate的時候遇到一個問題,在已有一個不帶參數的delegate基礎上,試圖再增加一個帶參數的delegate,結果VS報了“already contains a definition for ‘InvokeDelegate’”這樣的錯誤。
第一眼看上去,代碼似乎沒什麼問題:
InvokeDelegate( param);
其實這是把delegate等同於了method,所以才會認為使用method的重載方式也可以重載delegate。
翻過《CLR via C#》這本書,或者直接用ILDASM工具查看就會明白,delegate在編譯時會被編譯器翻譯成一個繼承MulticastDelegate的類。
因此,delegate真實的代碼應該是這樣的:
InvokeDelegate(Object IAsyncResult BeginInvoke(AsyncCallback callback, Object InvokeDelegate(Object IAsyncResult BeginInvoke( param, AsyncCallback callback, Object }
這樣就不難看出,之前的寫法會生成同樣名稱的兩個類,這個當然是不被允許的。而兩者唯一的區別就在於BeginInvoke方法中的參數。
那麼是否就沒有辦法重載delegate了呢?
再看看.NET Framework中已有的Action委托。Action,Action,Action……各種形式都有。看一下它們的語法。
Action委托:public delegate void Action()
Action委托:public delegate void Action(T obj)
Action委托:public delegate void Action(T1 arg1, T2 arg2)
顯然使用泛型的方式可以實現重載delegate的需求。
如果把“private delegate void InvokeDelegate(string param);”改成“private delegate void InvokeDelegate<in T>(T param);”,會生成以下的新類。
InvokeDelegate<T> InvokeDelegate(Object IAsyncResult BeginInvoke(T param, AsyncCallback callback, Object }
這種寫法便不會與第一個delegate發生沖突了。
不過最後需要補充的是,重載delegate這樣的說法並不正確,其實只是定義了不同類型的delegate,而非發生了重載操作。
原文同步發布於我的個人博客