views:

58

answers:

1

I am having trouble understanding what the rules are for passing delegates in C#3.0. The final .Max() is giving the compile error as shown below, but I can't understand what the significant difference is between that case and any of the others.

int NamedIdentity(int val) { return val; }
Func<int, int> Identity = x => x;

void Main() {
    var range = Enumerable.Range(1, 10);

    range.Max();
    range.Max(x => x);
    range.Max(Identity);
    range.Max((Func<int, int>) NamedIdentity);
    range.Max(new Func<int, int>(NamedIdentity));

    // this line gives compile error
    range.Max(NamedIdentity); 
    /* The call is ambiguous between the following methods or properties: 
    * 'System.Linq.Enumerable.Max<int>(System.Collections.Generic.IEnumerable<int>, System.Func<int,decimal>)' and 
    * 'System.Linq.Enumerable.Max<int>(System.Collections.Generic.IEnumerable<int>, System.Func<int,decimal?>)'
    */
}

Why does this not compile? My understanding is that NamedIdentity is declared as a Func<int, int>, so it does not need to be casted, although obviously I'm wrong. One clue is that the compile error is talking about Decimals even though none are referenced anywhere in the code. Where did that come from? Can a function reference not be implicitly cast to a delegate of the same signature?

+3  A: 

The C# 3.0 compiler will not implicitly cast a method group to a delegate when resolving generic parameters.
This was fixed in C# 4.0.

SLaks
Any idea why the compile error is mentioning Decimals?
recursive
@recursive: I believe because those are the first two overloads. I'm not entirely sure.
SLaks