2010-10-22 50 views
3

我想在lambda表達式使用方法組,這樣的:爲什麼添加返回類型會阻止我使用方法組語法?

public class Foo { public void Hello(string s) { } } 

void Test() 
{ 
    // this works as long as Hello has a void return type 
    Func<Foo, Action<string>> a = foo => foo.Hello; 
} 

當我改變的Hello返回類型int,不過,我得到

「酒吧。你好(字符串)'有錯誤的返回類型。

我試圖代替ActionFunc玩耍,但似乎阻止我使用方法組語法。

任何想法?我的目標是能夠引用許多具有不同返回類型和大量字符串參數的方法,我甚至不打算稱它們 - 我只想反思它們的屬性。不喜歡lambda表達式的安全,然而,而不只是鍵入方法名字符串)


編輯:澄清我的理由爲希望使用Action<string>int在我的例子可以是任意數量的類型。我試着模板化該類型 -

void Set<T>(Func<Foo, Func<string, T>> a) { } 
void Test() { Set(foo => foo.Hello); } // fails 

- 但是編譯器不能得到T(大概因爲我不能在返回類型超載同樣的原因?)。

還有其他想法嗎?在這種情況下,我不反對某些瘋狂的反思,只要我可以讓編譯器檢查該方法組的名稱即可。

回答

7

當它具有非無效返回類型時,它不再與Action<string>兼容。換句話說,這將失敗過:

int Foo(string s) { return 10; } 

// Error: wrong return type 
Action<string> action = new Action<string>(Foo); 

爲什麼這是不允許的原因,看到"The void is invariant"埃裏克利珀的博客文章。

你應該能夠使用方法組的語法是這樣的:

public class Foo { public int Hello(string s) { return 10; } } 

void Test() 
{ 
    Func<Foo, Func<string, int>> a = foo => foo.Hello; 
} 

,在這兩種VS2008和VS2010對我的作品。對C#4的方法組轉換和類型推斷進行了一些更改 - 不幸的是細節讓我不知所措 - 但我不相信這種情況會受到這些更改的影響。

+0

有趣的博客文章。不幸的是,我希望在我的示例右側存在的值的返回類型各不相同。我更新了一些信息。 – ladenedge 2010-10-22 16:13:03

+0

讀者也可能對另一個相關的Lippert博客文章[Method Group Conversion Variance]感興趣(http://blogs.msdn.com/b/ericlippert/archive/2007/10/19/covariance-and-contravariance-in- C-部分三人基團的轉化率 - variance.aspx)。 – ladenedge 2011-01-04 20:55:39

6

對於void返回類型,foo.Hello是Action<string>。使用int返回類型,現在是Func<string, int>

要處理多個返回類型 - 假設你不需要有返回值做任何事情 - 你可以平凡包裝非void函數這樣的:

Func<Foo, Action<string>> a = foo => s => foo.Hello(s); 
+0

感謝您的答案 - 不幸的是,我試圖在我的真實程序中「分組」的方法都是不同的返回類型。我更新了一些信息。 – ladenedge 2010-10-22 16:15:22

+0

@ladenedge:我已經修改了我的答案(希望)可以解決您的評論。 – 2010-10-23 00:19:42

+0

我通常喜歡這個想法,但問題是我失去了方法組語法! (或者至少,我似乎無法在不顯式傳遞's'的情況下編譯它。)正如我上面提到的,我不僅有一堆返回類型,而且還有一堆字符串參數 - d真的很想避免把它們全部機械地傳遞給每一個'Hello'的外觀。 – ladenedge 2010-10-23 05:00:48

相關問題