1. 程式人生 > >[C#] 委託與方法組

[C#] 委託與方法組

在編寫委託相關程式碼,尤其是泛型委託相關程式碼的時候,經常會遇到下面這種問題:

定義一個委託型別:

public delegate void TestDelegate<T>(T arg);

定義一個測試用的類,及方法:
public class TestClass
{
    public void TestFunc4Delegate(int arg){}
    public void TestFunc1(Delegate dele){}
    public void TestFunc2<T>(TestDelegate<T> dele){}
}

測試用的程式碼:
1.    TestClass tc = new TestClass();
2.    tc.TestFunc1(tc.TestFunc4Delegate);
3.    tc.TestFunc2(tc.TestFunc4Delegate);

然後會發現,上面的測試用程式碼有編譯錯誤,其中第二行的編譯錯誤是“無法從方法組轉換為System.Delegate”,第三行的編譯錯誤是“無法從用法中推匯出TestClass.TestFunc2<T>(TestDelegate<T>)的型別實參”。

以上報錯的核心問題就在“方法組”上。“方法組”是一個編譯器概念,由於C#支援方法過載,所以名字相同的方法可能會有多種過載實現方式,這所有的名稱相同的過載方法合在一起就成為一個方法組。上面的例子中tc.TestFunc4Delegate實際上指向的是名為Test4Delegate的方法組,儘管上面的類定義中並沒有對Test4Delegate做任何過載,它依然是一個方法組。

既然是方法組,那麼問題就來了——無法確定需要的到底是方法組中的哪一個過載。正因為確定不了,所以編譯器無法決定用什麼委託子型別來建立委託例項,同樣也就無法推匯出泛型的正確型別。

想要讓上例中的呼叫可以通過編譯,就必須指定限定型別,如這樣:

tc.TestFunc1((TestDelegate<int>)tc.TestFunc4Delegate);
tc.TestFunc2<int>(tc.Test4Delegate);