Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple Linq expression won't compile

Having these basic definitions

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

I'm wondering why this won't compile :

var b = strings.Select(MyFunc);

But this will:

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

The error message is "The type arguments for method 'System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerable, System.Func)' cannot be inferred from the usage."

The Resharper error tip says it's confused between

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

and

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

...but the signature for MyFunc is clear - it just takes one (string) parameter.

Can anyone shed some light here?

like image 756
Cristian Diaconescu Avatar asked Mar 09 '11 11:03

Cristian Diaconescu


2 Answers

Generic type inference changed slightly - in terms of implementation - between the C# 3 and C# 4 compiler. Here's a short but complete example program:

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;
    }
}

That compiles with the C# compiler in .NET 4, but not the one in .NET 3.5.

I think it's reasonable to call this a bug fix, as I don't think it was a spec change.

If you have to use the compiler from .NET 3.5, you can add a cast to clarify:

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

or

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

or you could make the type argument explicit:

var results = strings.Select<string, bool>(MyFunc);
like image 50
Jon Skeet Avatar answered Nov 18 '22 19:11

Jon Skeet


Jon is of course correct as usual. Some additional information:

Here's the blog article from 2007 where I describe the problem you're having:

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

Based on the feedback on that article we decided to fix this, but could not get the fix into C# 3 for scheduling reasons.

A few months after that I announced that the fix would go into C# 4, not into the C# 3 service pack:

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

like image 33
Eric Lippert Avatar answered Nov 18 '22 21:11

Eric Lippert