如果将无参数方法组传递给LINQ方法,为什么无法推断类型?

时间:2017-12-07 16:02:01

标签: c# linq

有人可以解释我(或显示规范/文档)为什么不允许关注:

string[] fiveFoos = Enumerable.Range(1, 5).Select(GetFoo).ToArray();

...

static string GetFoo()
{
    return "Foo";
}

只有这会编译:

string[] fiveFoos = Enumerable.Range(1, 5).Select(i => GetFoo()).ToArray();

Enumerable.Range投射的整数是不相关的,方法GetFoo是无参数的并且明确返回String,所以为什么我仍然会遇到编译器错误:

  

错误CS0411方法'Enumerable.Select(IEnumerable,Func)'的类型参数不能是   从用法推断。尝试指定类型参数   明确。

2 个答案:

答案 0 :(得分:7)

Select此处需要Func<int, string> - 您的GetFoo方法需要int才能生效。

方法组转换通过推断采用适当参数的方法的重载来工作 - 这里没有。 The integer projected from Enumerable.Range is not relevant - 在这个用例中,它可能与您无关,但它与编译器有关!!

答案 1 :(得分:4)

  

Enumerable.Range投射的整数不相关,方法GetFoo无参数且显然返回String

区别在于GetFoo方法是无参数的,而i => GetFoo() lambda则不是。添加忽略其参数的lambda会将GetFoo()方法的签名与Func<int,T>期望的Enumerable.Select方法的签名相匹配。

定义一个从无参数生成器生成序列的简单方法可以解决这个问题:

static class MyEnumerable {
    public static IEnumerable<T> Generate<T>(Func<T> f, int n) {
        while (n > 0) {
            n--;
            yield return f();
        }
    }
}

现在你可以写

string[] fiveFoos = MyEnumerable.Generate(GetFoo, 15).ToArray();

Demo.