2012-03-18 35 views
6

我試圖寫一個函數,函數作爲它的一個參數 - 我以前做過很多次的任務。這工作得很好:功能可以運行一個方向,而不是其他

int RunFunction(Func<int,int> f, int input) { 
    return f(input); 
} 
int Double(int x) { 
    return x*2; 
} 

// somewhere else in code 
RunFunction(Double,5); 

然而,這不起作用:

public static class FunctionyStuff { 
    public static int RunFunction(this Func<int,int> f, int input) { 
     return f(input); 
    } 
} 

// somewhere else in code 
Double.RunFunction(5); 

任何想法,爲什麼第一個作品,第二個不?

回答

5

第一個版本正在執行方法組轉換作爲「參數參數」匹配的一部分。這種轉換不適用於擴展方法。對於拉姆達表達式也是如此 - 你不能寫:

((int x) = > x * 2).RunFunction(10); 

要麼。

科C#4規範的7.6.5.2給出擴展方法調用的細節。

expr.identifier () 
expr.identifier (args) 
expr.identifier <typeargs> () 
expr.identifier <typeargs> (args) 

表達式(expr)的類型,然後在此規則中使用:

延伸方法C中它通過要求該方法調用是一個這些形式開始關閉我 .M Ĵ資格如果

  • expr到第一個參數M j的類型存在隱式身份,參考或裝箱轉換。

規範的註釋版本則包括來自埃裏克利珀此評論:

此規則確保使擴展double的方法不還擴展int。它還確保在匿名函數或方法組上沒有定義擴展方法。

+0

也許你也應該解釋爲什麼* *它不發生的擴展方法和lambda表達式。這是因爲他們沒有特定的委託類型。 'Func鍵'和'假設可能MyIntIntDelegate'具有相同的簽名,但將是不同的類型,所以編譯器可能不知道要轉換成哪一個。 – Timwi 2012-03-18 00:18:53

+0

所以如果我得到這個權利,在第一個版本中有一個從'Method'到'Func'的隱式轉換? – Joe 2012-03-18 00:19:56

+0

@Timwi:我正在那裏... – 2012-03-18 00:24:11

0

Extension Methods「被稱爲好像他們是在擴展類型實例方法」。

在你的情況Double是不是一個實例,所以你不能調用擴展方法就可以了。

相關問題