This question is based off of the results from another SO question of mine. My new question is not a question of how can I get X to work, but why doesn't X work.

I've created a simplified example of my problem, however if you want to see the practical application/situation I'm using this, look at my original question (the below functions don't actually do anything useful).

T bar<T>(Func<T, bool> f) { return default(T); }
bool foo(int i) { return true; }

Now I have 3 lines of code that do work as expected and all do the same thing purpose wise.

int num;
num = bar<int>(foo);
num = bar(new Func<int, bool>(foo));
num = bar((int i) => true );

My question is "Why do I need to explicitly specify T for bar for the first example?" The reason I wonder this is because the compiler turns the first two examples into the same line of code. Using ILSpy I see that the code compiles to this.

num = Program.bar<int>(new Func<int, bool>(Program.foo));
num = Program.bar<int>(new Func<int, bool>(Program.foo));
num = Program.bar<int>((int i) => true);

I don't understand why the compiler can't infer the type from the fact that I only have one function called foo, and it does fit the template so to speak. Now if I had created another function bool foo(bool i) I would understand if the compiler complained that there was some ambiguity and it didn't know which one I wanted and that I should specify the type argument explicitly.

This of course is just me being lazy, but it is just something I was expecting and was surprised when the compiler wasn't picking up my slack.

有帮助吗?

解决方案

I'm on the bus, so, short answer.

type inference of t requires knowing the formal parameter type of the delegate type in the argument.

conversion of the method group to the delegate type does overload resolution as though the method group was invoked with the arguments of the formal parameter types of the target delegate.

but those types are what we are trying to deduce!

this is circular reasoning, so type inference rejects it. A method group conversion requires that the formal parameter types be deduced from some other argument.

you have no other arguments.

so inference fails.

that the group contains only one method is irrelevant. It would be bizarre if adding more methods to the group caused inference to fail. The rule that a group of overloads is resolved through overload resolution is a sensible one, and that requires knowing the parameters. You don't get to run the inferences backwards just because a method group happens to be a singleton.

see the type inference tag on my msdn blog for a longer article on this topic.

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top