2011-03-09 37 views
10

有了這些基本的定義簡單的LINQ表達式將無法編譯

bool MyFunc(string input) 
{ 
    return false; 
} 
var strings = new[] {"aaa", "123"}; 

我不知道爲什麼這不會編譯:

var b = strings.Select(MyFunc); 

但這會:

var c = strings.Select(elem => MyFunc(elem)); 

錯誤消息是「方法的類型參數System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerab le,System.Func)'不能從使用中推斷出來。「

ReSharper的錯誤提示說,它混淆

之間
Select(this IEnumerable<string>, Func<string, TResult>) 

Select(this IEnumerable<string>, Func<string, int, TResult>) 

...但MYFUNC簽名是明確的 - 它只是需要一個(字符串)參數。

任何人都可以在這裏發光?

回答

14

通用類型推斷在C#3和C#4編譯器之間稍有變化 - 就實現而言。下面是一個簡短但完整的示例程序:

using System; 
using System.Linq; 

class Test 
{ 
    static void Main() 
    { 
     string[] strings = { "a", "b" }; 
     var results = strings.Select(MyFunc); 
    } 

    static bool MyFunc(string input) 
    { 
     return true; 
    } 
} 

,隨着.NET 4的C#編譯器編譯,而不是一個在.net 3.5。

認爲這是合理的稱這是一個錯誤修復,因爲我不認爲這是一個規範的變化。

如果你必須使用從.NET 3.5的編譯器,你可以添加一個投澄清:

var results = strings.Select((Func<string,bool>) MyFunc); 

var results = strings.Select(new Func<string,bool>(MyFunc)); 

,或者你可以讓類型參數明確:

var results = strings.Select<string, bool>(MyFunc); 
+0

所以*不*不合理的我覺得編譯器會想辦法... – 2011-03-09 12:52:56

+0

@Cristi:不...儘管試圖從規範中辨別出它應該如何工作是棘手的。我認爲規範中的類型推斷部分就是將「這裏是龍」寫成的。 – 2011-03-09 12:54:44

+0

我們決定改變這種行爲,當它變成C#3時已經太遲了,所以我們把它放在C#4中。 – 2011-03-09 15:25:55

6

喬恩當然是正常的。一些額外的信息:

下面是從2007年的博客文章中,我描述你所遇到的問題:

http://blogs.msdn.com/b/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx

基於對文章中,我們決定解決這個問題的反饋,但不能得到出於調度原因修復C#3。

幾個月之後,我宣佈的解決將進入C#4,不進C#3的服務包:

http://blogs.msdn.com/b/ericlippert/archive/2008/05/28/method-type-inference-changes-part-zero.aspx