3
static void Main()
        {
string[] a = { "a", "asd", "bdfsd", "we" };
            a = a.OrderBy(fun).ToArray();
}

 private static int fun(string s)
        {
            return s.Length;
        }

its is giving compile time error . I know that we can do this with Lambda expression like this. a.OrderBy(s=>s.Length).ToArray(); but i want to this do by defining different function . What mistake i have done?

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
freak
  • 463
  • 4
  • 7
  • Code you wrote seems to compile and execute well, what error did you receive ? – Dynami Le Savard May 11 '10 at 15:37
  • Cannot infer the type parameters for `Enumerable.OrderBy` – SLaks May 11 '10 at 15:40
  • The type arguments for method 'System.Linq.Enumerable.OrderBy(System.Collections.Generic.IEnumerable, System.Func)' cannot be inferred from the usage. Try specifying the type arguments explicitly. – SLaks May 11 '10 at 15:49
  • 2
    Anyone who is able to compile this code is using the C# 4 compiler which can infer generic type arguments from method group return types. Please see my answer for more information. – Andrew Hare May 11 '10 at 15:56
  • I am using C# 3 complier. So, it is not able to infer the type parameters of `OrderBy`. – freak May 11 '10 at 16:13

3 Answers3

6

The expression fun is an untyped expression called a method group.
Since a method group has no type, the compiler cannot infer the type parameters of the generic OrderBy method.

You need to explicitly pass the type parameters, like this:

a = a.OrderBy<string, int>(fun).ToArray();

Or,

a = a.OrderBy(new Func<string, int>(fun)).ToArray();
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • I was under the impression that you actually could...wouldn't `fun` be inferred as a Func ? I am confused because I copied his code and compiled and executed fine on .NET 3.5 without touching it. – Dynami Le Savard May 11 '10 at 15:47
  • @Dynami: It only fails if you pass a method group (as opposed to a delegate variable) I tried it; it does fail (The type arguments for method 'System.Linq.Enumerable.OrderBy(System.Collections.Generic.IEnumerable, System.Func)' cannot be inferred from the usage. Try specifying the type arguments explicitly.) – SLaks May 11 '10 at 15:49
  • 2
    Hm, I retried it with my goody ol' VS2008, and you seem to be correct. So I guess under VS2010 with a .NET 3.5 project I actually am compiling with the C#4 compiler, did not know that. – Dynami Le Savard May 11 '10 at 16:03
4

SLaks is correct in that the C# 3 compiler will not allow this but it is important to point out that the C# 4 compiler will compile your example without issue.

Andrew Hare
  • 344,730
  • 71
  • 640
  • 635
3

Here's what happened. When I first implemented the method type inference algorithm for C# 3 I reasoned as SLaks suggests: method groups have no type, nothing was inferred from them in C# 2, and overload resolution needs to pick the method out of the method group by knowing the types of the arguments, which is precisely what we are trying to infer; this is a chicken and egg problem. I blogged about that in November of 2007:

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

There was so much pushback on this that we decided to revisit the issue and change the type inference algorithm so that we made inferences from method groups provided enough inferences had already been done that overload resolution could proceed on the method group.

Unfortunately that change came too late in the cycle and did not make it into C# 3. We postponed it to C# 4, and there you go.

I blogged about that in 2008:

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

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067