2016-11-21 69 views
2

所以在這裏我想通過一個方法與隨機簽名的Foo方法的參數。但沒有任何運氣。
問題是我可以通過任何操作。但是在一個方法上。
任何幫助?C#:傳遞的方法具有可變參數的另一種方法

class Bar 
{ 
    void M1(int a) { } 
    void M2(string a, int b) { } 

    Action<string, int, bool> A1 = (s, i, b) => {}; 
    Action<int, float> A2 = (i, f) => {}; 

    void Foo(Delegate f) {} 

    void Test() 
    { 
     Foo(A1); 
     Foo(A2); 
     // Foo(M1); // nope 
     // Foo(M2); // no way 
    } 
} 

PS。我試圖在Unity3d的Mono下運行。

+1

這是不特定於unity3d或單聲道的,它只是語言的一部分。 「M1」和「M2」是「方法組」而非代表。一個方法組可以轉換爲任何兼容的委託類型,並且編譯器拒絕從空中選擇一個(比如'Action'或'Func'類型)。 –

+0

是的,我知道。我剛剛提到過,以防有人根據C#3.0+的獨特功能提出解決方案。 – dotsquid

回答

4

你必須轉換爲具體的委託類型要做到這一點,就像這樣:

void Test() 
{ 
    Foo(A1); 
    Foo(A2); 
    Foo((Action<int>) M1); 
    Foo((Action<string, int>)M2); 
} 

這樣做的原因是M1M2是所謂的法團。這僅僅意味着它們指的是一種或多種方法。爲什麼它可以不止一個?因爲您可能有多個名稱爲M1的方法,每個方法都接受不同的參數集。但是,即使你只是一個過載,像你的情況,有可能是該超載簽名兼容多種委託類型(可能是被宣佈爲委託無效YourDelegateType(INT ARG),或任何其他Action<int>YourDelegateType)。

這也就是爲什麼從方法組的隱式轉換委派,你必須投方法組特定的委託類型明確。

+0

有一件事是可能存在多重過載。但在這種情況下,每個名稱「M1」和「M2」只有一個過載。另一件事是可能存在多個兼容的具體委託類型。例如,與'空隙M3(對象A,INT B){}'(僅此單過載)時,呼叫'美孚(M3);'可以代表任一'美孚((動作)M3);'或' Foo((EventHandler )M3);'。甚至是'Foo((MyDel)M3);'MyDel'是你自己創建的某種類型。 'Action <,>'在C#中沒有特殊的狀態,所以編譯器不會從無操作中選擇'Action <,>'。 –

+1

此外,由於共和逆變是可能的方法組轉換,可以有時使用另一組類型參數。繼續我之前的例子,'Foo((動作)M3);'和'Foo((動作)M3)'都是可能的。 –

+0

的確有好處。因此很明顯,即使只存在一個重載,如果沒有明確選擇委託類型,也無法將方法組轉換爲委託。 – Evk

相關問題