Brian Snow
Brian Snow

Reputation: 1143

Type inference discrepancy between method and extension method arguments

Let's say I have the following method defined:

int ReturnNumber(int number)
{
    return number;
}

Now, let's say that I also have the following two methods defined; a regular method:

void Print(Func<int, int> function)

and an extension method:

static void Print(this Func<int, int> function)

I can call the former like this:

Print(ReturnNumber); // Regular method call, seems to implicitly convert ReturnNumber to Func<int, int>

but I can't do that with the latter:

ReturnNumber.Print(); // Extension method call, does not seem to do the implicit conversion -- results in compiler error

though I can do this:

((Func<int, int>)ReturnNumber).Print(); // I perform the conversion explicitly

I'm assuming that there's some "magic" that happens when you pass a method as an argument to another method, and that the compiler is therefore able to guess that it should try to convert the ReturnNumber to Func<int, int>, whereas the compiler doesn't do any such thing for extension methods. Is this correct? My question can be summarized as: why can't you call an extension method on a method, whereas you can call an extension method on a delegate instance? Does it have something to do with the fact that the compiler doesn't treat methods as objects, but only treats delegates as objects?

Upvotes: 5

Views: 64

Answers (1)

Servy
Servy

Reputation: 203825

That method group can be implicitly converted to Func<int, int>, which means if you're using that method group in a location where a Func<int, int> is expected (such as by passing it to a method who's parameter is Func<int, int> then it's able to convert it into such a delegate.

But until you've actually converted that method group into a Func<int, int> you can't call any instance methods on it, as it has none. When you explicitly cast it to a Func<int, int> then you're changing that expression from a method group (which isn't itself a Func<int, int>) into a Func<int, int>.

Upvotes: 5

Related Questions