<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>C# 3.0 Return Type Inference Does Not Work On Method Groups</title><link>http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx</link><description>Thanks all for your excellent feedback on my variance series. I am still reading and digesting the feedback and I shall take it to the language design committee later this month. Returning to less hypothetical but equally complicated issues, today, what</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>re: C# 3.0 Return Type Inference Does Not Work On Method Groups</title><link>http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx#5918122</link><pubDate>Mon, 05 Nov 2007 23:30:07 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5918122</guid><dc:creator>David V. Corbin</dc:creator><description>&lt;P&gt;Eric, I think you just committed "Developer Overloading" &amp;lt;grin&amp;gt;, My brain HURTS.&lt;/P&gt;
&lt;P&gt;Actually a very well written explaination. I have often tried to explain the inference process to my clients, only to be met with blank stares. This post will definately help in that regard.&lt;/P&gt;
&lt;P&gt;Cheerrs!&lt;/P&gt;</description></item><item><title>re: C# 3.0 Return Type Inference Does Not Work On Method Groups</title><link>http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx#5921850</link><pubDate>Tue, 06 Nov 2007 02:04:41 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5921850</guid><dc:creator>Luke</dc:creator><description>&lt;P&gt;I'm a bit confused:&lt;/P&gt;
&lt;P&gt;S GetCity&amp;lt;X, S&amp;gt;(X x) { …&lt;/P&gt;
&lt;P&gt;var fails = customers.Select(GetCity); // [1]&lt;/P&gt;
&lt;P&gt;var alsoFails = customers.Select(c=&amp;gt;GetCity(c)); // [2]&lt;/P&gt;
&lt;P&gt;If we had overload resolution that only fails when type information cannot be derived, is there a case where [2] would work and [1] would not? &amp;nbsp;(I don't see how this could be possible.) &amp;nbsp;Perhaps the devil is in the details, but I don't see why it's that hard to specify that overload resolution fails if all the types cannot be determined. &amp;nbsp;Could you shed some light on some of the "subtly incompatible set of overload resolution rules" that would be needed?&lt;/P&gt;</description></item><item><title>re: C# 3.0 Return Type Inference Does Not Work On Method Groups</title><link>http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx#5923142</link><pubDate>Tue, 06 Nov 2007 03:14:46 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5923142</guid><dc:creator>Eric Lippert</dc:creator><description>&lt;P&gt;You are correct in that if overload resolution is going to fail for the method group, then it is going to fail in the lambda as well. &lt;/P&gt;
&lt;P&gt;The subtlety is this: suppose we decided to go ahead and do overload resolution anyway. &amp;nbsp;In this case we would then deduce that S is R, and therefore deduce that R is... R. &amp;nbsp;&lt;/P&gt;
&lt;P&gt;What should we do in that case? &amp;nbsp;Should we have overload resolution pick a different method? &amp;nbsp;That would then be changing the overload resolution rules in a subtle and confusing way.&lt;/P&gt;
&lt;P&gt;Suppose we didn't do that. Suppose we added R to R's boundary set. Now suppose we had a different inference path, say from a third argument, from which we would deduce that R is string. &amp;nbsp;Now what do we do to resolve the conflict? &amp;nbsp;There is no implicit conversion from string to R or R to string, so we'd have to have inference fail.&lt;/P&gt;
&lt;P&gt;Which seems bad. &amp;nbsp;We could then say well, never add R to R's bounds set. &amp;nbsp;Just ignore it if that happens. &amp;nbsp;Keep on trucking. Which is another subtle change to the type inference algorithm.&lt;/P&gt;
&lt;P&gt;And then you have to think about what happens if we are deducing not that R is R, but that, say, R is IConvertible&amp;lt;R&amp;gt;. &amp;nbsp;Or what if there are more complex relationships between the type variable, the inferred return type, and other types in the bounds set.&lt;/P&gt;
&lt;P&gt;It gets to be a big mess, and all because we have a circularity whereby we are trying to make an inference both from and to the same thing at the same time. It's logically weird and we just don't want to go there.&lt;/P&gt;</description></item><item><title>re: C# 3.0 Return Type Inference Does Not Work On Method Groups</title><link>http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx#5924768</link><pubDate>Tue, 06 Nov 2007 04:43:40 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5924768</guid><dc:creator>qrli</dc:creator><description>&lt;P&gt;Sorry I'm lost in your inference. If we have already get Func&amp;lt;Customer, R&amp;gt;, didn't we already know the argument list of GetCity()? Then it should be straightforward to pick an overload of GetCity() and find the return type. Why does it have to determine return type for overload resolution?&lt;/P&gt;</description></item><item><title>re: C# 3.0 Return Type Inference Does Not Work On Method Groups</title><link>http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx#5926345</link><pubDate>Tue, 06 Nov 2007 06:10:14 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5926345</guid><dc:creator>Luke</dc:creator><description>&lt;P&gt;After working on this problem for a while, I realized the same thing as qrli. &amp;nbsp;You should never have made the return and argument type parameters in your posts on variance different than Func&amp;lt;A, R&amp;gt;. :-p &amp;nbsp;I can't decide whether this is important though, due to the fact that we need to imply a delegate type. &amp;nbsp;Is there no way for the type inference engine to know that a method's arguments are completely specified by Func&amp;lt;Customer, R&amp;gt; and that only one overload could possibly be chosen?&lt;/P&gt;
&lt;P&gt;You describe the unbroken circle problem when dealing with the generic version of GetCity. &amp;nbsp;However, is it not possible to try overloads that would be a better match than your generic version, overloads for which there are no unknown type parameters? &amp;nbsp;If both the generic and non-generic versions exist and I write the lambda as above, the non-generic version will be chosen. &amp;nbsp;(I assume this is due to §14.4.2.2 of the C# spec.)&lt;/P&gt;
&lt;P&gt;If the generic version of GetCity is the only one that exists, [2] fails, so I don't know why we're worrying about making [1] work.&lt;/P&gt;
&lt;P&gt;Does overload resolution with lambda methods include any of the subtleties you are trying to avoid with non-lambda overload resolution?&lt;/P&gt;</description></item><item><title>re: C# 3.0 Return Type Inference Does Not Work On Method Groups</title><link>http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx#5933965</link><pubDate>Tue, 06 Nov 2007 14:34:40 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5933965</guid><dc:creator>Richard</dc:creator><description>&lt;P&gt;Perhaps this is a stupid question (I don't know C# very well) but... are there any cases where automatically rewriting:&lt;/P&gt;
&lt;P&gt;var cities = customers.Select(GetCity);&lt;/P&gt;
&lt;P&gt;as:&lt;/P&gt;
&lt;P&gt;var cities = customers.Select(c=&amp;gt;GetCity(c));&lt;/P&gt;
&lt;P&gt;will do the wrong thing? It seems blatantly obvious that the former is unambiguous, in the given case, so it seems to me to be a bug if C# can't work that out for itself.&lt;/P&gt;</description></item><item><title>re: C# 3.0 Return Type Inference Does Not Work On Method Groups</title><link>http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx#5937318</link><pubDate>Tue, 06 Nov 2007 17:46:26 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5937318</guid><dc:creator>Eric Lippert</dc:creator><description>&lt;P&gt;&amp;gt; Why does it have to determine return type for overload resolution?&lt;/P&gt;
&lt;P&gt;Overload resolution goes like this (simplified):&lt;/P&gt;
&lt;P&gt;* Add all nongeneric methods in the method group to the candidate set.&lt;/P&gt;
&lt;P&gt;* Do type inference on all generic methods and add all successful inferences to the candidate set.&lt;/P&gt;
&lt;P&gt;* Remove all the nonapplicable methods (ie, where arguments do not go to parameter types) &amp;nbsp;from the candidate set.&lt;/P&gt;
&lt;P&gt;* Choose the unique best candidate from the applicable candidates.&lt;/P&gt;
&lt;P&gt;You have to determine the return type in order to do step two -- make type inferences on generic methods.&lt;/P&gt;</description></item><item><title>re: C# 3.0 Return Type Inference Does Not Work On Method Groups</title><link>http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx#5937366</link><pubDate>Tue, 06 Nov 2007 17:49:37 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5937366</guid><dc:creator>Eric Lippert</dc:creator><description>&lt;P&gt;&amp;gt; However, is it not possible to try overloads that would be a better match than your generic version, overloads for which there are no unknown type parameters? &lt;/P&gt;
&lt;P&gt;Yes. That is exactly what I mean by making a subtle change to the overload resolution algorithm just for this case. &lt;/P&gt;
&lt;P&gt;We could mess with the overload resolution algorithm in all the ways you suggest, and we'd then have _two_ overload resolution algorithms, one for regular code and one for nested type inference on method groups, which would produce sublty different results. &amp;nbsp;We don't want to go there.&lt;/P&gt;</description></item><item><title>re: C# 3.0 Return Type Inference Does Not Work On Method Groups</title><link>http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx#5937408</link><pubDate>Tue, 06 Nov 2007 17:52:30 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5937408</guid><dc:creator>Eric Lippert</dc:creator><description>&lt;P&gt;&amp;gt; If both the generic and non-generic versions exist and I write the lambda as above, the non-generic version will be chosen.&lt;/P&gt;
&lt;P&gt;That rule only comes into effect when there is an exact tie, ie, you have Foo(int) and Foo&amp;lt;T&amp;gt;(T) in the candidate set and you call Foo(1). &amp;nbsp;Type inference makes Foo&amp;lt;int&amp;gt; a candidate and the nongeneric is then chosen by the betterness algorithm.&lt;/P&gt;
&lt;P&gt;One of the subtleties that you'd run into by messing with the overload resolution algorithm is that now generic methods that otherwise would be chosen as the better match disappear from the candidate set seemingly inexplicably.&lt;/P&gt;</description></item><item><title>re: C# 3.0 Return Type Inference Does Not Work On Method Groups</title><link>http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx#5937556</link><pubDate>Tue, 06 Nov 2007 18:01:26 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5937556</guid><dc:creator>Eric Lippert</dc:creator><description>&lt;P&gt;&amp;gt; It seems blatantly obvious that the former is unambiguous&lt;/P&gt;
&lt;P&gt;Sure, it is. And we could write a new rule, say, that return type inference from method groups is legal only when it is "blatantly obvious" what method the&amp;nbsp;method group refers to. But we'd then have to write a new "blatantly obvious overload resolution" algorithm which was different from the regular overload resolution algorithm. And now, again, we have two overload resolution algorithms.&lt;/P&gt;
&lt;P&gt;I think my point here has been somewhat lost. &amp;nbsp;Let me restate it:&lt;/P&gt;
&lt;P&gt;* the specification for return type inference from a lambda explicitly does NOT require the target delegate type to be known.&lt;/P&gt;
&lt;P&gt;* the specification for overload resolution on a method group explicitly DOES require the target delegate type to be known. &amp;nbsp;It's not necessary in absolutely every case, but the algorithm does call for knowing what the return type is for overload resolution on a method&amp;nbsp;group containing generic methods.&lt;/P&gt;
&lt;P&gt;* in the type inference scenario, the target delegate type is exactly what we are trying to infer; it is unknown.&lt;/P&gt;
&lt;P&gt;* therefore it is rather nonsensical to specify that we ought to use overload resolution as an explicit part of return type inference&lt;/P&gt;
&lt;P&gt;Or, even more briefly:&lt;/P&gt;
&lt;P&gt;* We have designed the type inference algorithm so that we always infer from known to unknown at every step. Return type inference on method groups as specified requires sometimes inferring from unknown to unknown. That wasn't our intention, it wasn't what we implemented, and it got into the published specification by accident.&lt;/P&gt;</description></item><item><title>re: C# 3.0 Return Type Inference Does Not Work On Method Groups</title><link>http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx#5940945</link><pubDate>Tue, 06 Nov 2007 21:13:43 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5940945</guid><dc:creator>Luke</dc:creator><description>&lt;p&gt;&amp;gt; One of the subtleties that you'd run into by messing with the overload resolution algorithm is that now generic methods that otherwise would be chosen as the better match disappear from the candidate set seemingly inexplicably.&lt;/p&gt;
&lt;p&gt;I keep returning to this and it's bothering me -- do you have an example of such a generic method?&lt;/p&gt;
</description></item><item><title>re: C# 3.0 Return Type Inference Does Not Work On Method Groups</title><link>http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx#5949094</link><pubDate>Wed, 07 Nov 2007 05:12:51 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5949094</guid><dc:creator>qrli</dc:creator><description>&lt;p&gt;For now, I can understand the case when there is a GetCity&amp;lt;S, R&amp;gt;() generic overload, and it is understandable that the generic parameters cannot be deduced. But I think it will surprise most programmers that it won't work if there's only non-generic GetCity(). &lt;/p&gt;
&lt;p&gt;I tend to think that there's something wrong with method-group-to-delegate conversion, or accurately, deduction. The conversion from method group to delegate appears to be so significant althought the syntax intents to hide the complexity. I used to think it is trivial but I was surprised to find that Control.Invoke() doesn't accept a method group.&lt;/p&gt;
&lt;p&gt;So I got the same question as Richard. Why cannot you do the conversion in the lambda way instead of the method-group-to-delegate way? It seems more powerful to treat method group as a terser form of lambda expression.&lt;/p&gt;
</description></item><item><title>re: C# 3.0 Return Type Inference Does Not Work On Method Groups</title><link>http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx#5955395</link><pubDate>Wed, 07 Nov 2007 12:52:07 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5955395</guid><dc:creator>Stefan Wenig</dc:creator><description>&lt;p&gt;qrli, Richard,&lt;/p&gt;
&lt;p&gt;do you mean resolving the method group as if it were a lambda call, or actually generating a method that does the call? &lt;/p&gt;
&lt;p&gt;Just resolving it like this would be fine with me, although I figure Eric's gonna tell us that this is too much of a special case. Still, it would remove this horrible case where noone will understand why referring does not work!&lt;/p&gt;
&lt;p&gt;Acutally generating this method would result in some overhead, and I'm not sure if it is acceptable to introduce this overhead just to enable deferring. &lt;/p&gt;
&lt;p&gt;Just creating an actual method if the method group cannot be resolved otherwise would create a speial case too, plus it would mean that you have to guess if any overhead is invisibly created, you won't see it in the code. This is hardly how languages like C# work. (Then again, while it is easier to figure out whether an anonymous delegate/lambda results in a closure might be easier than this, it could still be considered a precedent that we don't actually care about such minor performance penalties. After all, the costs of a closure are MUCH higher than creating a method for just passing stuff through).&lt;/p&gt;
&lt;p&gt;I understand the language designer's perspective, but in this case I'd vote for some kind of fix that resolves this from a user's perspective. I think it might even be easier to understand the rules of inference if they are the same for method groups as for lambdas. But then again, it might not, and it might lead to breaking changes with existing C# 2.0 code.&lt;/p&gt;
</description></item><item><title>re: C# 3.0 Return Type Inference Does Not Work On Method Groups</title><link>http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx#6212255</link><pubDate>Wed, 14 Nov 2007 17:43:19 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6212255</guid><dc:creator>Luke</dc:creator><description>&lt;p&gt;Eric, have you abandoned this post (or perhaps been ultra-busy)? &amp;nbsp;The question in my comment above was for you...&lt;/p&gt;
</description></item><item><title>Fabulous Adventures In Coding</title><link>http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx#8328801</link><pubDate>Fri, 21 Mar 2008 12:19:28 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8328801</guid><dc:creator>Vincent</dc:creator><description>&lt;p&gt;Ayende在使用.Net3.0的时候遇到了这样一个问题Csc.exeanddelegateinference,or:WhyC#hasawkwardsyntax Co...&lt;/p&gt;
</description></item><item><title>Fabulous Adventures In Coding</title><link>http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx#8328831</link><pubDate>Fri, 21 Mar 2008 12:47:04 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8328831</guid><dc:creator>cnblogs.com</dc:creator><description>&lt;p&gt;Ayende 在使用.Net 3.0的时候遇到了这样一个问题 Csc.exe and delegate inference, or: Why C# has awkward syntax Code highlighting&lt;/p&gt;
</description></item><item><title>Method Type Inference Changes, Part Zero</title><link>http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx#8556675</link><pubDate>Wed, 28 May 2008 18:46:14 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8556675</guid><dc:creator>Fabulous Adventures In Coding</dc:creator><description>&lt;p&gt;Back in November I wrote a bit about a corner case in method type inference which does not work as expected&lt;/p&gt;
</description></item></channel></rss>