views:

451

answers:

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?

+1  A: 

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
I was under the impression that you actually could...wouldn't `fun` be inferred as a Func<string, int> ? I am confused because I copied his code and compiled and executed fine on .NET 3.5 without touching it.
Dynami Le Savard
@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<TSource,TKey>(System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource,TKey>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.)
SLaks
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
+2  A: 

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
+2  A: 

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