<?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>Method Type Inference Changes, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2008/06/17/method-type-inference-changes-part-one.aspx</link><description>I want to start this by discussing the purpose of method type inference, and clearing up some potential misunderstandings about type inference errors. First off though, a brief note on nomenclature. Throughout this series when I say "type inference" I</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>re: Method Type Inference Changes, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2008/06/17/method-type-inference-changes-part-one.aspx#8614800</link><pubDate>Wed, 18 Jun 2008 10:10:19 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8614800</guid><dc:creator>Konstantin Triger</dc:creator><description>&lt;p&gt;An implementation question:&lt;/p&gt;
&lt;p&gt;Quoting you:&lt;/p&gt;
&lt;p&gt;&amp;quot;Type inference infers T as Customer, but cannot figure out what R is because Customer does not have a property FristName. Therefore type inference fails, ...&amp;quot;.&lt;/p&gt;
&lt;p&gt;It seems that at this point you can say: &amp;quot;Compilation fails&amp;quot;. Why do you need to see it as an inference failure and then go back to find the &amp;quot;user friendly&amp;quot; cause? It looks correct to stop processing in a case a member was not found in a type and report an error.&lt;/p&gt;
&lt;p&gt;In a more general case you will probably try to infer T as other type and if it's possible check whether it has &amp;quot;FristName&amp;quot; property. So the generic error I would expect here is something like: &amp;quot;Neither of types &amp;lt;Customer,'other inferred types if exist'&amp;gt; has a property named 'FirstName'&amp;quot;.&lt;/p&gt;
</description></item><item><title>re: Method Type Inference Changes, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2008/06/17/method-type-inference-changes-part-one.aspx#8615498</link><pubDate>Wed, 18 Jun 2008 12:56:09 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8615498</guid><dc:creator>configurator</dc:creator><description>&lt;p&gt;At that point, the method has not been selected yet, so the type T as Customer.&lt;/p&gt;
&lt;p&gt;i.e., there might be another Select in the candidate pool, which would make that code valid - The contents of the lambda cannot be compiled (or even generate an error) until the method is selected; The method cannot be selected because the contents cannot compile. This recursion is exactly the problem that Eric is refering to.&lt;/p&gt;
</description></item><item><title>re: Method Type Inference Changes, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2008/06/17/method-type-inference-changes-part-one.aspx#8617329</link><pubDate>Wed, 18 Jun 2008 19:36:49 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8617329</guid><dc:creator>nikov</dc:creator><description>&lt;p&gt;Hi, Eric.&lt;/p&gt;
&lt;p&gt;&amp;gt;If they can, then the constructed generic method stays in the candidate set; if inference fails then it is removed. &lt;/p&gt;
&lt;p&gt;&amp;gt;Then all methods which are inapplicable -- that is, the arguments cannot be converted to the parameter types -- are removed.&lt;/p&gt;
&lt;p&gt;One important thing which happens between these two steps -- check that once the inferred type arguments are substituted for the corresponding method type parameters, all constructed types in the parameter list satisfy their constraints, and if they do not -- remove this generic method. This step differs from the final validation of constaraints on the best method itself (if it is generic), which happens after overload resolution.&lt;/p&gt;
&lt;p&gt;In the following example the method A.Foo is removed early due to constraint on the delegate F&amp;lt;T&amp;gt;, and so the extension method is invoked. If we remove the constraint from the delegate, A.Foo becomes the best method and then compilation fails.&lt;/p&gt;
&lt;p&gt;using System;&lt;/p&gt;
&lt;p&gt;class A&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;delegate T F&amp;lt;T&amp;gt;() where T : class;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;void Foo&amp;lt;T&amp;gt;(F&amp;lt;T&amp;gt; x) where T : class { }&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;static void Main()&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;new A().Foo(() =&amp;gt; 1);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;static class B&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;public static void Foo&amp;lt;T&amp;gt;(this T x, Func&amp;lt;int&amp;gt; f) { }&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
</description></item><item><title>re: Method Type Inference Changes, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2008/06/17/method-type-inference-changes-part-one.aspx#8617389</link><pubDate>Wed, 18 Jun 2008 19:49:47 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8617389</guid><dc:creator>Eric Lippert</dc:creator><description>&lt;p&gt;Indeed, I am glossing over a number of important steps here. &lt;/p&gt;
&lt;p&gt;Also, as a result of a bug that I think was one of yours, we also check to see whether any of the inferred types would be illegal because they are not accessible in the caller's context.&lt;/p&gt;
</description></item><item><title>re: Method Type Inference Changes, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2008/06/17/method-type-inference-changes-part-one.aspx#8620117</link><pubDate>Thu, 19 Jun 2008 07:23:27 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8620117</guid><dc:creator>Tanveer Badar</dc:creator><description>&lt;p&gt;The user would be correct to expect as clear an error message as possible, in that example. Because missing property on the type is the real problem.&lt;/p&gt;
&lt;p&gt;I appreciate the work gone/going into improving error messages. Now, only if I could convince my ridiculous management to move to C#3.0.&lt;/p&gt;
</description></item><item><title>re: Method Type Inference Changes, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2008/06/17/method-type-inference-changes-part-one.aspx#8642497</link><pubDate>Mon, 23 Jun 2008 18:36:12 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8642497</guid><dc:creator>kostat</dc:creator><description>&lt;p&gt;To configurator:&lt;/p&gt;
&lt;p&gt;Basically the inference algorithm can be seen as a series of:&lt;/p&gt;
&lt;p&gt;&amp;lt;hypothesis&amp;gt; -&amp;gt; &amp;lt;test&amp;gt; -&amp;gt; … &amp;nbsp;&lt;/p&gt;
&lt;p&gt;As the implementation is described, it assumes some &amp;lt;hypothesis&amp;gt; (T is Customer), then makes a &amp;lt;test&amp;gt; (does Customer has a property named 'FristName'?). The &amp;lt;test&amp;gt; fails and invalidates &amp;lt;hypothesis&amp;gt;.&lt;/p&gt;
&lt;p&gt;Since the user is interested which &amp;lt;test&amp;gt; failed, the implementation then uses some heuristic to find the &amp;lt;test&amp;gt;. My point is that it is always known. See again Eric's explanation: &amp;quot;if inference fails then it [the candidate] is removed&amp;quot;. In fact what fails is the &amp;lt;test&amp;gt;! So there can be a situation where we need to remove unneeded &amp;lt;test&amp;gt;s in our error message, but never - to find them again.&lt;/p&gt;
</description></item><item><title>re: Method Type Inference Changes, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2008/06/17/method-type-inference-changes-part-one.aspx#8661116</link><pubDate>Fri, 27 Jun 2008 13:35:55 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8661116</guid><dc:creator>RuneFS</dc:creator><description>&lt;p&gt;I had an interresting (at lest to me) experience. I had the following few lines of code:&lt;/p&gt;
&lt;p&gt;public IDictionary&amp;lt;string, IDictionary&amp;lt;string, object&amp;gt;&amp;gt; Find&amp;lt;TKey&amp;gt;(IEnumerable&amp;lt;TKey&amp;gt; searchValues, IDictionary&amp;lt;string, Type&amp;gt; requireColumns) {&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;IDictionary&amp;lt;int, string&amp;gt; keys;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;keys = searchValues.ToDictionary(x =&amp;gt; Convert.ToInt32(x), x =&amp;gt; identifiers[x]);&lt;/p&gt;
&lt;p&gt;that works fine the types of the ToDictionary can be inferred, but chagning the last line to:&lt;/p&gt;
&lt;p&gt;keys = searchValues.ToDictionary(Convert.ToInt32, x =&amp;gt; identifiers[x]);&lt;/p&gt;
&lt;p&gt;fails. My question is how come that the inferrance fails in the last version? after all the type of the first argument is the same and can be determined or am I missing something?&lt;/p&gt;
</description></item><item><title>re: Method Type Inference Changes, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2008/06/17/method-type-inference-changes-part-one.aspx#8661908</link><pubDate>Fri, 27 Jun 2008 18:05:40 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8661908</guid><dc:creator>Eric Lippert</dc:creator><description>&lt;p&gt;Reread part zero of this series. &amp;nbsp;Your question is the whole reason I'm doing this series in the first place.&lt;/p&gt;
</description></item><item><title>re: Method Type Inference Changes, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2008/06/17/method-type-inference-changes-part-one.aspx#8670638</link><pubDate>Mon, 30 Jun 2008 10:41:29 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8670638</guid><dc:creator>RuneFS</dc:creator><description>&lt;p&gt;Thanks for pointing that out, i'll get back to part zero at once :-)&lt;/p&gt;
</description></item></channel></rss>