2017-08-09 114 views
0

我有以下的本地方法。爲什麼我的通用高階函數不接受方法組作爲參數?

void Test(int i, int j, int k) { 
    Console.WriteLine($"{i} {j} {k}"); 
} 

,我有以下

public static class Curry { 
    public static Func<T0, T1, Action<T2>> 
     act2f3<T0, T1, T2>(Action<T0, T1, T2> fn) => 
      (T0 t0, T1 t1) => (T2 t2) => fn(t0, t1, t2); 

} 

它拆分原有的功能分爲兩個函數調用定義高階函數。第一個函數接受前兩個參數,第二個函數接受最後一個參數。當調用第二個函數時,將使用所有參數調用原始函數。

一個簡單的用法是

var cfn = Curry.act2f3(Test); 
var cfn2 = cfn(0,1); 
cfn2(3); 

輸出cfn2被稱爲後應

"0 1 3"  

但是C#編譯器將不允許這樣做。

方法'Curry.act2f3(Action)'的類型參數不能從用法中推斷出來。嘗試明確指定類型 參數。

但是下面沒有工作

Curry.act2f3((int i, int j, int k) => Test(i, j, k)); 

,但並不能真正幫助,因爲它違背了擺在首位寫這個庫的目的。目的是操作函數參數的一個DRY過程。

有沒有一個微妙的技巧,我錯過了這個工作?

+2

泛型類型推斷沒有實現深度啓發式,它會經常停止一層,或者在它能夠推斷出涉及的類型然後吐出該錯誤之前。 –

+0

我經常將方法組傳遞給LINQ函數,這沒有問題。這裏的具體問題是什麼,阻止方法組與lambdas可以互換? – bradgonesurfing

+0

這裏的部分問題(我認爲)有兩種推演類型,委託在'Test'周圍進行構造,以及方法中的泛型類型。如果你試試這個:'Curry.act2f3(new Action (Test));'然後編譯。 –

回答

0

這是不幸的c#編譯器不能參考傳入函數的類型參數Test

因爲您在聲明(int i, int j, int k)中指定了int類型,因此Curry.act2f3((int i, int j, int k) => Test(i, j, k));聲明有效。

var cfn = Curry.act2f3<int, int, int>(Test);

var cfn = Curry.act2f3(Test);如果指定了泛型類型這樣會工作。

相關問題