简单的Linq表达式将无法编译

时间:2011-03-09 11:18:30

标签: c# linq .net-3.5 .net-4.0

有这些基本定义

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.IEnumerable,System.Func)'的类型参数。”

Resharper错误提示说它在

之间感到困惑
Select(this IEnumerable<string>, Func<string, TResult>)

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

...但MyFunc的签名是明确的 - 它只需要一个(字符串)参数。

有人能在这里说清楚吗?

2 个答案:

答案 0 :(得分: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));

或者您可以将type参数设为显式:

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

答案 1 :(得分:6)

Jon像往常一样当然是正确的。一些其他信息:

以下是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