<?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>Fabulous Adventures In Coding : Breaking Changes</title><link>http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx</link><description>Tags: Breaking Changes</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Closing over the loop variable, part two</title><link>http://blogs.msdn.com/ericlippert/archive/2009/11/16/closing-over-the-loop-variable-part-two.aspx</link><pubDate>Mon, 16 Nov 2009 16:18:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9923025</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>44</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9923025.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9923025</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Thanks to everyone who left thoughtful and insightful comments on last week's post.&lt;/P&gt;
&lt;P&gt;More countries&amp;nbsp;really ought to implement Instant Runoff Voting; it would certainly appeal to the geek crowd. Many people left complex opinions of the form "I'd prefer to make the change, but if you can't do that then make it a warning". Or "don't make the change, do make it a warning", and so on.&amp;nbsp;But what I can deduce from reading the comments is that there is a general lack of consensus on what the right thing to do here is. In fact, I just did a quick tally:&lt;/P&gt;
&lt;P&gt;Commenters who expressed support for a warning: 26&lt;BR&gt;Commenters who expressed the sentiment "it's better to not make the change": 24&lt;BR&gt;Commenters who expressed the sentiment "it's better to make the change": 25&lt;/P&gt;
&lt;P&gt;Wow. I guess we'll flip a coin. :-)&amp;nbsp;&amp;nbsp;&amp;nbsp; (*)&lt;/P&gt;
&lt;P&gt;Four people suggested to actually make it an error to do this. That's a pretty big breaking change, particularly since we would be breaking not just "already broken" code, but plenty of code that works perfectly well today -- see below. That's not likely to happen.&lt;/P&gt;
&lt;P&gt;People also left a number of interesting suggestions. I thought I'd discuss some of those a little bit.&lt;/P&gt;
&lt;P&gt;First off, I want to emphasize that what we're attempting to address here is the problem that &lt;STRONG&gt;the language encourages people to write code that has different semantics than they think it has&lt;/STRONG&gt;. The problem is NOT that the language has no way to express the desired semantics; clearly it does. Just introduce a new variable explicitly into the loop.&lt;/P&gt;
&lt;P&gt;A number of suggestions were for ways that the language could more elegantly express that notion. Some of the suggestions:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;foreach(var x in c) &lt;STRONG&gt;inner&lt;/STRONG&gt; &lt;BR&gt;&lt;STRONG&gt;foreachnew&lt;/STRONG&gt;(var x in c)&lt;BR&gt;foreach(&lt;STRONG&gt;new&lt;/STRONG&gt; var x in c)&lt;BR&gt;foreach(var x&amp;nbsp;&lt;STRONG&gt;from&lt;/STRONG&gt; c) &lt;BR&gt;foreach(var x&amp;nbsp;&lt;STRONG&gt;inside&lt;/STRONG&gt; c) &lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Though we could do any of those, none of them by themselves solve the problem at hand. Today, you have to know to use a particular pattern with foreach to get the semantics you want: declare a variable inside the loop. With one of these changes, you still have to know to use a particular keyword to get the semantics you want, and it is still easy to accidentally do the wrong thing. &lt;/P&gt;
&lt;P&gt;Furthermore,&amp;nbsp;a change so small and so targetted at such a narrow scenario probably does not provide enough benefit to justify the large cost of creating a new syntax, particularly one which is still easily confused with an existing syntax.&lt;/P&gt;
&lt;P&gt;C++ luminary Herb Sutter happened to be in town and was kind enough to stop by my office to describe to me how they are solving a related problem in C++. Apparently the next version of the C++ standard will include lambdas, and they're doing this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;&lt;EM&gt;[q, &amp;amp;r]&lt;/EM&gt; &lt;STRONG&gt;(int x) -&amp;gt; int&lt;/STRONG&gt; { return M(x, q, r); }&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This means that the lambda captures outer variable q by value, captures r by reference, takes an int and returns an int. Whether the lambda captures values or references is controllable! An interesting approach but one that doesn't immediately solve our problem here; we cannot make lambdas capture by value by default without a huge breaking change. Capturing by value would have to require new syntax, and then we're in the same boat again: the user has to know to use the new syntax when in a foreach loop.&lt;/P&gt;
&lt;P&gt;A number of people also asked what the down sides of adding a warning are. The down side is that &lt;STRONG&gt;a warning which warns about correct behaviour is a very bad warning&lt;/STRONG&gt;; it makes people change working code, and frequently they break working code in order to eliminate a warning that shouldn't have been present in the first place. Consider:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;foreach(var insect in insects)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; var query = frogs.Where(frog=&amp;gt;frog.Eats(insect));&lt;BR&gt;&amp;nbsp; Console.WriteLine("{0} is eaten by {1} frogs.", insect, query.Count());&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This makes a lambda closed over insect; the lambda never escapes the loop, so there's no problem here. But the compiler doesn't know that. The compiler sees that the lambda is being passed to a method called Where, and Where is allowed to do anything with that delegate, including storing it away to be called later. Which is exactly what Where does! Where stores away the lambda into a monad that represents the execution of the query. The fact that the &lt;STRONG&gt;query object doesn't survive the loop&lt;/STRONG&gt; is what keeps this safe. But how is the compiler supposed to suss out that tortuous chain of reasoning? We'd have to give a warning for this case, even though it is perfectly safe. &lt;/P&gt;
&lt;P&gt;It gets worse. A lot of people are required by their organizations to compile with "warnings are errors" turned on. Therefore, any time we introduce a new warning for a pattern that is often actually safe and frequently used, we are effectively causing an enormous breaking change. A vaccine which kills more healthy people than the disease would have is probably not a good bet. (**)&lt;/P&gt;
&lt;P&gt;This is not to say that a warning is a bad idea, but that it is not the obvious slam dunk good idea that it initially appears to be.&lt;/P&gt;
&lt;P&gt;A number of people suggested that the problem was in the training of the developers, not in the design of the language. I disagree. Obviously modern languages are complex tools that require training to use, but we are working hard to make a language where people's natural intuitions about how things work lead them to write correct code. I have myself made this error a number of times, usually in the form of writing code like the code above, and then refactoring it in such a manner that suddenly some part of it escapes the loop and the bug is introduced. It is very easy to make this mistake, even for experienced developers who thoroughly understand closure semantics. That's a flaw in the design of the language. &lt;/P&gt;
&lt;P&gt;And finally, a number of people made suggestions of the form "make it a warning in C# 4, and an error in C# 5", or some such thing. FYI, C# 4 is DONE. We are only making a few last-minute "user is electrocuted"-grade bug fixes, mostly based on your excellent feedback from the betas. (If you have bug reports from the beta, please keep sending them, but odds are good they won't get fixed for the initial release.) We are certainly not capable of introducing any sort of major design change or new feature at this point. And we try to not introduce semantic changes or new features in service packs. We're going to have to live with this problem for at least another cycle, unfortunately.&lt;/P&gt;
&lt;P&gt;********&lt;/P&gt;
&lt;P&gt;(*) Mr. Smiley Face indicates that Eric is indulging in humourous japery.&lt;/P&gt;
&lt;P&gt;(**) I wish to emphasize that I am 100% in favour of vaccinations for deadly infectious&amp;nbsp;diseases, &lt;EM&gt;even vaccines that are potentially dangerous&lt;/EM&gt;. The number of people made ill or killed by the smallpox vaccine was tiny compared to the number of people who did not contract this deadly, contagious (and now effectively extinct)&amp;nbsp;disease as a result of mass vaccination. I am a strong supporter of vaccine research. I'm just making an analogy here people.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9923025" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/foreach/default.aspx">foreach</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/closures/default.aspx">closures</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/coin+flipping/default.aspx">coin flipping</category></item><item><title>Closing over the loop variable considered harmful</title><link>http://blogs.msdn.com/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx</link><pubDate>Thu, 12 Nov 2009 14:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9918689</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>124</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9918689.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9918689</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;I don't know why I haven't blogged about this one before; this is the single most common incorrect bug report we get. That is, someone thinks they have found a bug&amp;nbsp;in the compiler, but in fact the compiler is correct and their code is wrong. That's a terrible situation for everyone; we very much wish to design a language which does not have "gotcha" features like this. &lt;/P&gt;
&lt;P&gt;But I'm getting ahead of myself. What's the output of this fragment?&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;var&amp;nbsp;values = new List&amp;lt;int&amp;gt;() { 100, 110, 120 };&lt;BR&gt;var&amp;nbsp;funcs = new List&amp;lt;Func&amp;lt;int&amp;gt;&amp;gt;();&lt;BR&gt;foreach(var v in values) &lt;BR&gt;&amp;nbsp; funcs.Add( ()=&amp;gt;v );&lt;BR&gt;foreach(var f&amp;nbsp;in funcs) &lt;BR&gt;&amp;nbsp; Console.WriteLine(f());&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Most people expect it to be 100 / 110 / 120.&amp;nbsp; It is in fact 120 / 120 / 120. Why?&lt;/P&gt;
&lt;P&gt;Because &lt;SPAN class=code&gt;()=&amp;gt;v&lt;/SPAN&gt; means "return &lt;STRONG&gt;the current value of variable v&lt;/STRONG&gt;", not "return the value v was back when the delegate was created". &lt;STRONG&gt;Closures close over variables, not over values.&lt;/STRONG&gt; And when the methods run, clearly the last value that was assigned to v was 120, so it still has that value.&lt;/P&gt;
&lt;P&gt;This is very confusing. The correct way to write the code is:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;foreach(var v in values) &lt;BR&gt;{&lt;BR&gt;&amp;nbsp; var v2 = v;&lt;BR&gt;&amp;nbsp; funcs.Add( ()=&amp;gt;v2 );&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Now what happens? Every time we re-start the loop body, we logically create a fresh new variable v2. Each closure is closed over a different v2, which is only assigned to once, so it always keeps the correct value. &lt;/P&gt;
&lt;P&gt;Basically, the problem arises because we specify that the foreach loop is a syntactic sugar for&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;&amp;nbsp; {&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IEnumerator&amp;lt;int&amp;gt; e = ((IEnumerable&amp;lt;int&amp;gt;)values).GetEnumerator();&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int m; // OUTSIDE THE ACTUAL LOOP&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while(e.MoveNext())&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m = (int)(int)e.Current;&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;funcs.Add(()=&amp;gt;m);&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; finally&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (e != null) ((IDisposable)e).Dispose();&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR minmax_bound="true"&gt;&amp;nbsp; }&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;If we specified that the expansion was&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while(e.MoveNext())&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int m; // INSIDE&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m = (int)(int)e.Current;&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;funcs.Add(()=&amp;gt;m);&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;then the code would behave as expected.&lt;/P&gt;
&lt;P&gt;It's compelling to consider fixing this for a hypothetical future version of C#, and I'd like to hear your feedback on whether we should do so or not. The reasons FOR making the change are clear; this is a big confusing "gotcha" that real people constantly run into, and LINQ, unfortunately, only makes it worse, because it is likely to increase the number of times&amp;nbsp;a customer is going to use a closure in a loop. Also, it seems reasonable that the user of the&amp;nbsp;foreach loop&amp;nbsp;might&amp;nbsp;think of&amp;nbsp;there being&amp;nbsp;a "fresh" loop variable every time, not just a fresh value in the same old variable. Since the foreach loop variable is not mutable by user code, this reinforces the idea that it is a succession of values, one per loop iteration, and not "really" the same variable over and over again. And finally, the change has no effect whatsoever on non-closure semantics. (In fact, in C# 1 the spec was not clear about whether the loop variable went inside or outside, since in a world without closures, it makes no difference.)&lt;/P&gt;
&lt;P&gt;But that said, there are some very good reasons for not making this change.&lt;/P&gt;
&lt;P&gt;The first reason is that obviously this would be a breaking change, and we hates them, my precious. Any developers who depend on this feature, who require the closed-over variable to contain the last value of the loop variable, would be broken. I can only hope that the number of such people is vanishingly small; this is a strange thing to depend on. Most of the time, people do not expect or depend on this behaviour.&lt;/P&gt;
&lt;P&gt;Second, it makes the foreach syntax lexically inconsistent. Consider &lt;SPAN class=code&gt;foreach(int x in M())&lt;/SPAN&gt; The header of the loop has two parts, a declaration &lt;SPAN class=code&gt;int x&lt;/SPAN&gt; and a collection expression, &lt;SPAN class=code&gt;M()&lt;/SPAN&gt;. The &lt;SPAN class=code&gt;int x&lt;/SPAN&gt; is to the left of the &lt;SPAN class=code&gt;M()&lt;/SPAN&gt;. Clearly the &lt;SPAN class=code&gt;M()&lt;/SPAN&gt; is not inside the body of the loop; that thing only executes once, before the loop starts. So &lt;EM&gt;why should something to the collection expression's left be inside the loop&lt;/EM&gt;? This seems inconsistent with our general rule that stuff to the left logically "happens before" stuff to the right. The declaration is lexically NOT in the body of the loop, so why should we treat it as though it were?&lt;/P&gt;
&lt;P&gt;Third, it would make the "foreach" semantics inconsistent with "for" semantics. We have this same problem in "for" blocks, but "for" blocks are much looser about what "the loop variable" is; there can be more than one variable declared in the for loop header, it can be incremented in odd ways, and it seems implausible that people would consider each iteration of the "for" loop to contain a fresh crop of variables. When you say &lt;SPAN class=code&gt;for(int i; i &amp;lt; 10; i += 1)&lt;/SPAN&gt; it seems dead obvious that the "i += 1" means "increment the loop variable" and that there is one loop variable for the whole loop, not a new fresh variable "i" every time through! We certainly would not make this proposed change apply to "for" loops.&lt;/P&gt;
&lt;P&gt;And fourth, though this is a nasty gotcha, there is an easy workaround, and tools like ReSharper detect this pattern and suggest how to fix it. We could take a page from that playbook and simply&amp;nbsp;issue a compiler warning on this pattern. (Though adding new warnings brings up a whole raft of issues of&amp;nbsp;its own, which I might get into in another post.)&amp;nbsp;Though this is vexing, it really doesn't bite that many people that hard, and it's not a big deal to fix, so why go to the trouble and expense of taking a breaking change for something with an easy fix?&lt;/P&gt;
&lt;P&gt;Design is, of course, the art of compromise in the face of many competing principles. "Eliminate gotchas" in this case directly opposes other principles like "no breaking changes", and "be consistent with other language features". Any thoughts you have on pros or cons of us taking this breaking change in a hypothetical future version of C# would be greatly appreciated. &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9918689" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx">Language Design</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/foreach/default.aspx">foreach</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/closures/default.aspx">closures</category></item><item><title>The void is invariant</title><link>http://blogs.msdn.com/ericlippert/archive/2009/06/29/the-void-is-invariant.aspx</link><pubDate>Mon, 29 Jun 2009 17:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9756024</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>19</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9756024.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9756024</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;[UPDATES below]&amp;nbsp;&lt;/P&gt;
&lt;P&gt;A while back I described &lt;A href="http://blogs.msdn.com/ericlippert/archive/2007/10/19/covariance-and-contravariance-in-c-part-three-member-group-conversion-variance.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/10/19/covariance-and-contravariance-in-c-part-three-member-group-conversion-variance.aspx"&gt;a kind of variance that we’ve supported since C# 2.0.&lt;/A&gt; When assigning a method group to a delegate type, such that both the selected method and the delegate target agree that their return type is a reference type, then the conversion is allowed to be covariant. That is, you can say:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;Giraffe GetGiraffe() { … }&lt;BR&gt;…&lt;BR&gt;Func&amp;lt;Animal&amp;gt; f = GetGiraffe;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This works logically because anyone who calls f must be able to handle any animal that comes back. The actual method claims to only return animals, and in fact, makes the stronger claim to only return giraffes. &lt;/P&gt;
&lt;P&gt;This works out in the CLR because the bits that make up a reference to an instance of Giraffe are exactly the same bits that make up a reference to that Giraffe interpreted as an instance of Animal. We can allow this magical conversion to happen because the CLR guarantees that it will all just work out without going in there and having to futz around with the bits.&lt;/P&gt;
&lt;P&gt;This is why this trick only works with reference types. A method that returns, say, a double cannot be converted via a covariant conversion to a delegate type that expects the method to return an object. Somewhere there would have to be code emitted that takes the returned double and boxes it to object; the bits of a double and the bits of a reference to an object boxing a double are completely different.&lt;/P&gt;
&lt;P&gt;But why doesn’t this trick work with void types? Here we have a method that returns some sort of success or failure code. Maybe we don’t care what it returns.&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;static bool DoSomething(bool b)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; if (b) return DoTheThing();&lt;BR&gt;&amp;nbsp; else return DoTheOtherThing();&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;Action&amp;lt;bool&amp;gt; action = DoSomething;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This doesn’t work. Why not? The caller of the action is not even going to &lt;EM&gt;use&lt;/EM&gt; the returned value, so it doesn’t matter one bit what it is! Shouldn’t “void” be considered &lt;EM&gt;a supertype of all possible types&lt;/EM&gt; for the purposes of covariant return type conversions from method groups to delegate types?&lt;/P&gt;
&lt;P&gt;No, and I’ll tell you why.&lt;/P&gt;
&lt;P&gt;Consider what happens when you do this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;bool x = DoSomething(true);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;We spit out IL that does the following:&lt;/P&gt;
&lt;P&gt;(1) put true on the IL stack – the stack gets one deeper&lt;BR&gt;(2) call DoSomething – the argument is removed from the stack and the return value is placed on the stack.&amp;nbsp; Net, the stack stays the same size as before&lt;BR&gt;(3) stuff whatever on top of the stack into local variable x – the stack now returns to its original depth.&lt;/P&gt;
&lt;P&gt;Now consider what happens when you do this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;DoSomething(true);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;We spit out IL that does the first two steps as before. But we cannot stop there! There is now a bool on the IL stack which needs to be removed. We generate a pop instruction to represent the fact that the returned bool has been discarded.&lt;/P&gt;
&lt;P&gt;Now consider what happens when you do this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;action(true);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;The compiler believes that action is a void-returning method, so it does not generate a pop instruction. If we allowed you to stuff DoSomething into the action, then we would be allowing you to misalign the IL stack!&lt;/P&gt;
&lt;P&gt;But didn’t I say “&lt;A href="http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx"&gt;the stack is an implementation detail?&lt;/A&gt;” Yes, but &lt;EM&gt;that’s a different stack&lt;/EM&gt;. The CLI specification describes a “virtual machine” which passes around arguments and returned values on a stack. An implementation of the CLI is required to make something that behaves like the specified machine, but it is not required to do so in any particular manner. It is not required to use the million-bytes-per-thread stack supplied to each thread by the operating system as its implementation of the IL stack; that’s a convenient structure to use, of course, but it’s an implementation detail that it does so.&lt;/P&gt;
&lt;P&gt;(As an aside: when we implemented the script engines, we also first specified our own private stack-based virtual machine. When we implemented it, we decided to put the information about “return addresses” – that is, “what code do I run next?” on the system stack, but we put arguments and return values of script functions in a stack-shaped block of memory that we allocated on our own. This made building the JScript garbage collector easier.)&lt;/P&gt;
&lt;P&gt;In practice, the jitter uses the system stack for some things and registers for other things. Return values are actually often sent back in a register, not on the stack. But that implementation detail doesn’t help us out when deciding what the conversion rules are; we have to assume that the implementation can do no more than what the CLI specification says. Had the CLI specification said “the returned value of any function is passed back in a ‘virtual register’” rather than having it pushed onto the stack, then we could have made void-returning delegates compatible with functions that returned anything. You can always just ignore the value in the register. But that’s not what the CLI specified, so that’s not what we can do. &lt;/P&gt;
&lt;P&gt;[UPDATE]&lt;/P&gt;
&lt;P&gt;A number of people have asked in the comments why we do not simply generate a helper method that does what you want. That is, when you say&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;Action&amp;lt;bool&amp;gt; action = DoSomething;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;realize that as&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;static&amp;nbsp;void DoSomethingHelper(bool b)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp; bool result = DoSomething(b); // result is ignored&lt;BR&gt;}&lt;BR&gt;...&lt;BR&gt;Action&amp;lt;bool&amp;gt; action = DoSomethingHelper;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;We could do that. But where would you like the line to be drawn? Should you be able to assign a&amp;nbsp;reference to a method that returns an int to a Func&amp;lt;Nullable&amp;lt;int&amp;gt;&amp;gt;? We could spit a helper method that converts the int to a nullable int.&amp;nbsp;What about Func&amp;lt;double&amp;gt;? We could spit a helper method that converts the int to a double. What about Func&amp;lt;object&amp;gt;? We could spit a helper method that boxes the int, unexpectedly allocating memory off the heap every time you call it. What about a Func&amp;lt;Foo&amp;gt; where there is a user-defined implicit conversion from int to Foo?&lt;/P&gt;
&lt;P&gt;We could be spitting arbitrarily complex fixer-upper methods that would seamlessly "do what you meant to say", and we have to stop somewhere.&amp;nbsp;The exact semantics of what we&amp;nbsp;do and do not&amp;nbsp;fix up would have to be designed, specified, implemented, tested, documented, shipped to customers and maintained forever. Those are costs. Plus, &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/08/31/future-breaking-changes-part-two.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/08/31/future-breaking-changes-part-two.aspx"&gt;every time we add a new conversion rule to the language we add breaking changes&lt;/A&gt;. The costs of those breaking changes to our customers have to be factored in.&lt;/P&gt;
&lt;P&gt;But more fundamentally, one of the design principles of C# is "if &lt;STRONG&gt;you say something wrong then &lt;EM&gt;we tell you&lt;/EM&gt; rather than trying &lt;EM&gt;to guess what you meant&lt;/EM&gt;&lt;/STRONG&gt;". JScript is deliberately a "muddle on through and do the best you can" language; C# is not. If what you want to do is make a delegate to a helper method then you express that intention by going right ahead and making that method.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9756024" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Scripting/default.aspx">Scripting</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Code+Generation/default.aspx">Code Generation</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Conversions/default.aspx">Conversions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx">Covariance and Contravariance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Memory+Management/default.aspx">Memory Management</category></item><item><title>Reserved and Contextual Keywords</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/11/reserved-and-contextual-keywords.aspx</link><pubDate>Mon, 11 May 2009 18:07:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9593986</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>11</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9593986.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9593986</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Many programming languages, C# included, treat certain sequences of letters as “special”. &lt;/P&gt;
&lt;P&gt;Some sequences are so special that they cannot be used as identifiers. Let’s call those the “reserved keywords” and the remaining special sequences we’ll call the “contextual keywords”. They are “contextual” because the character sequence might one meaning in a context where the keyword is expected and another in a context where an identifier is expected.*&lt;/P&gt;
&lt;P&gt;The C# specification defines the following reserved keywords:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;abstract as base bool break byte case catch char checked class const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long namespace new null object operator out override params private protected public readonly ref return sbyte sealed short sizeof stackalloc static string struct switch this throw true try typeof uint ulong unchecked unsafe ushort using virtual void volatile while &lt;/SPAN&gt;
&lt;P&gt;The implementation also reserves the magic keywords &lt;SPAN class=code&gt;__arglist __makeref __reftype __refvalue&lt;/SPAN&gt; which are for obscure scenarios that I might blog about in the future. 
&lt;P&gt;Those are the keywords that we reserved in C# 1.0; no new reserved keywords have been added since. It is tempting to do so, but we always resist. Were we to add a new reserved keyword then any program that used that keyword as an identifier would break upon recompilation. Yes, you can always use a keyword as an identifier if you really want: &lt;SPAN class=code&gt;@typeof @goto = @for.@switch(@throw);&lt;/SPAN&gt; is perfectly legal, though more than a little weird. But we prefer to avoid as many breaking changes as possible.&lt;/P&gt;
&lt;P&gt;We also have a whole bunch of contextual keywords. &lt;/P&gt;
&lt;P&gt;The “preprocessor” † uses all the directives (&lt;SPAN class=code&gt;#define&lt;/SPAN&gt;, and so on) which of course were never valid identifiers in the first place. But it also uses contextual keywords &lt;SPAN class=code&gt;hidden default disable restore checksum&lt;/SPAN&gt;.&lt;/P&gt;
&lt;P&gt;C# 1.0 had contextual keywords &lt;SPAN class=code&gt;get set value add remove&lt;/SPAN&gt;.&lt;/P&gt;
&lt;P&gt;C# 2.0 added &lt;SPAN class=code&gt;where partial global yield alias&lt;/SPAN&gt;.&lt;/P&gt;
&lt;P&gt;C# 3.0 added &lt;SPAN class=code&gt;from join on equals into orderby ascending descending group by select let var&lt;/SPAN&gt;.&lt;/P&gt;
&lt;P&gt;C# 4.0 will add &lt;SPAN class=code&gt;dynamic&lt;/SPAN&gt;.&lt;/P&gt;
&lt;P&gt;Every time we add one of these we need to carefully design the grammar so that if possible, the use of the new contextual keyword does not possibly change the meaning of an existing program which used it. &lt;/P&gt;
&lt;P&gt;For example, when defining a partial class, the &lt;SPAN class=code&gt;partial&lt;/SPAN&gt; must go immediately before the &lt;SPAN class=code&gt;class&lt;/SPAN&gt;. Since there was never a legal C# 1.0 program where &lt;SPAN class=code&gt;partial&lt;/SPAN&gt; appeared immediately before &lt;SPAN class=code&gt;class&lt;/SPAN&gt;, we knew that adding this new feature to the grammar would not possibly break any existing programs.&lt;/P&gt;
&lt;P&gt;Or, another example. Consider &lt;SPAN class=code&gt;var x = 1;&lt;/SPAN&gt; – that could have been a legal C# 2.0 program if there was a type called var with a user-defined implicit conversion from int. The semantic analyzer for declaration statements checks to see whether there is a type called var that is accessible at the declaration; if there is then the normal declaration rules are used. Only if there is not such a type can we do the analysis as an implicitly typed local declaration.&lt;/P&gt;
&lt;P&gt;One might wonder why on earth we added five contextual keywords to C# 1.0, when there was no chance of breaking backwards compatibility. Why not just make &lt;SPAN class=code&gt;get set value add remove&lt;/SPAN&gt; into “real” keywords?&lt;/P&gt;
&lt;P&gt;Because we could easily get away with making them contextual keywords, and it seemed likely that real people would want to name variables or methods things like get, set, value, add or remove. So we left them unreserved as a courtesy. &lt;/P&gt;
&lt;P&gt;Those were easy to make contextual, unlike, say, &lt;SPAN class=code&gt;return&lt;/SPAN&gt;. That’s a lot harder to make a contextual keyword because then &lt;SPAN class=code&gt;return (10);&lt;/SPAN&gt; would be ambiguous; is that calling the method named “return” or returning ten? So we didn’t make any of the other reserved keywords into contextual keywords.&lt;/P&gt;
&lt;P&gt;*******&lt;/P&gt;
&lt;P&gt;(*) An unfortunate consequence of this definition is that &lt;SPAN class=code&gt;using&lt;/SPAN&gt; is said to be a reserved keyword even though its meaning depends on its context; whether the &lt;SPAN class=code&gt;using&lt;/SPAN&gt; begins a directive or a statement determines its meaning.&lt;/P&gt;
&lt;P&gt;(†) An unfortunate name, since “preprocessing” is not done before regular language processing. In C#, the so-called “preprocessing” happens during lexical analysis.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9593986" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_+4.0/default.aspx">C# 4.0</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx">Language Design</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/keywords/default.aspx">keywords</category></item><item><title>Future-Proofing A Design</title><link>http://blogs.msdn.com/ericlippert/archive/2009/01/16/future-proofing-a-design.aspx</link><pubDate>Fri, 16 Jan 2009 20:21:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9308334</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9308334.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9308334</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Last time on FAIC a user asked for guidance on the potential pitfalls of refactoring an automatic property into a regular explicit property. This is just an example of a far more general problem: how can we design programs so that they are easy to get right when things inevitably change in the future?&lt;/P&gt;
&lt;P&gt;This is an incredibly difficult question to answer, one which whole books could be written on. Today, I'll just give three general points to think about.&lt;/P&gt;
&lt;P&gt;First: &lt;U&gt;Premature generality is expensive.&lt;/U&gt; 
&lt;P&gt;&lt;B&gt;&lt;/B&gt;
&lt;P&gt;Designing code to be future-proof without a clear understanding of what the future holds often leads to excess generality; generality has very real costs, and they might be higher than the benefit accrued. 
&lt;P&gt;If you do a good job of solving the problem at hand with the tools at hand, if the code is clean and organized and has few moving parts, then it will be easier to generalize it in the future if you need to in order to solve a problem then. 
&lt;P&gt;&lt;STRONG&gt;Design your code to solve the well-understood problem.&lt;/STRONG&gt; If you design it to solve an unknown future problem, odds are good that you're going to solve it poorly, making even more work for the future. 
&lt;P&gt;Second: &lt;U&gt;Represent in your &lt;I&gt;model&lt;/I&gt; only those things which are &lt;I&gt;always&lt;/I&gt; in the problem domain and whose class relationships are &lt;I&gt;unchanging&lt;/I&gt;.&lt;/U&gt; 
&lt;P&gt;The relationships between the classes TrafficLight, TrafficSign, Vehicle, Car, Truck, Pedestrian, Roadway, Intersection, SignalTiming and RightOfWayLaw are likely to be eternal and unchanging. 
&lt;P&gt;Things change. The &lt;I&gt;semantics&lt;/I&gt; of a particular RightOfWayLaw might change subtly or grossly as the city council does its job. There might be &lt;EM&gt;new subclasses&lt;/EM&gt; of Vehicle created in the future. A specific traffic light might have a &lt;EM&gt;faulty implementation&lt;/EM&gt; that the rest of the system needs to handle gracefully. But each of these situations is about changing the implementation details of a class, never changing its &lt;EM&gt;relationships&lt;/EM&gt; with other classes. 
&lt;P&gt;If the class &lt;I&gt;relationships&lt;/I&gt; are future-proofed then it is a lot easier to edit the &lt;I&gt;implementations&lt;/I&gt; of those classes without having to worry that the whole system will thereby get messed up. 
&lt;P&gt;The easiest way to keep the relationships straight is to &lt;STRONG&gt;base them as much as possible on concepts directly from the problem domain&lt;/STRONG&gt;. 
&lt;P&gt;Third: &lt;U&gt;Keep your policies away from your mechanisms.&lt;/U&gt; 
&lt;P&gt;The &lt;EM&gt;mechanism&lt;/EM&gt; of a traffic light works the same way no matter what &lt;EM&gt;policies&lt;/EM&gt; like light timings at rush hour are.&amp;nbsp; If mechanisms (TrafficLight) are separated from policies (SignalTiming) then you can change the mechanism to a more efficient one without worrying that you’re going to inadvertently change policy, and can change policy without worrying that you’re going to break mechanism. 
&lt;P&gt;My earlier example of a bank balance was deliberately an example of what goes wrong when mechanism and policy become conflated. The “Balance” getter was originally a &lt;EM&gt;mechanism&lt;/EM&gt;, but after the edit, it became a &lt;EM&gt;security policy enforcement tool&lt;/EM&gt;. 
&lt;P&gt;You must then ask yourself, “where in this code do I care about &lt;EM&gt;enforcing&lt;/EM&gt; the policy, and where do I care about &lt;EM&gt;executing&lt;/EM&gt; the mechanism?” and make the appropriate edits. After the edit, everywhere that needs policy enforcement needs to use “Balance”, everywhere that needs to effect the action of the mechanism needs to use “balance”.&amp;nbsp; 
&lt;P&gt;What are the odds that there is going to be a bug introduced, given that we now have a difference which is important and almost invisible? Pretty high! This difference should probably be made more visible by renaming the backing store to something that calls it out as semantically different from the property accessor. 
&lt;P&gt;Let's bring this back to the question at hand. What guidance do we propose for future-proofing turning automatic properties into regular properties?&amp;nbsp; The guidance that I am proposing here is: 
&lt;UL&gt;
&lt;LI&gt;First, think about whether making the design general now to solve an unknown problem that you might not even have in the future is worthwhile.&lt;/LI&gt;
&lt;LI&gt;Second, make sure that the design in general makes the relationships between classes unchanging, even if the specifics of each class change.&lt;/LI&gt;
&lt;LI&gt;Third, consider whether that hypothetical future change to the property will be splitting apart its role as a mechanism from its role as an enforcer of policy; if this is going to be an important distinction, then consider getting that distinction into the class implementation early so that you don’t have to retrofit it in a tedious and error-prone manner later.&lt;/LI&gt;&lt;/UL&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9308334" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Code+Quality/default.aspx">Code Quality</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Software+development+methodology/default.aspx">Software development methodology</category></item><item><title>Automatic vs Explicit Properties</title><link>http://blogs.msdn.com/ericlippert/archive/2009/01/14/automatic-vs-explicit-properties.aspx</link><pubDate>Wed, 14 Jan 2009 20:11:25 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9308211</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>16</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9308211.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9308211</wfw:commentRss><description>&lt;div class="mine"&gt; &lt;p&gt;Here's a question I got from a C# user last year, a question I get fairly frequently:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font color="#000080"&gt;User: With “regular” explicit properties, I tend to use the private backing field directly from within the class. Of course, with an automatic property, you can’t do this. My concern is that in the future, if I decide I need an explicit property for whatever reason, I’m left with the choice of changing the class implementation to use the new private field, or continue going through the property. I’m not sure what the right thing to do in this case is.&lt;/font&gt; &lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;You say “for whatever reason”, and that's key. The answer to your question will depend &lt;b&gt;entirely&lt;/b&gt; upon what the reason was that motivated the change.  &lt;p&gt;If the reason that motivated the change from automatically implemented property to explicitly implemented property was to &lt;strong&gt;change the semantics&lt;/strong&gt; of the property then you should evaluate whether the desired semantics when accessing the property &lt;i&gt;from within the class&lt;/i&gt; are identical to or different from the desired semantics when accessing the property &lt;i&gt;from outside the class&lt;/i&gt;.  &lt;p&gt;If the result of that investigation is “from within the class, the desired semantics of accessing this property are &lt;i&gt;different&lt;/i&gt; from the desired semantics of accessing the property from the outside”, then your edit has introduced a bug. &lt;b&gt;You should fix the bug&lt;/b&gt;. If they are &lt;i&gt;the same&lt;/i&gt;, then your edit has not introduced a bug; &lt;b&gt;keep the implementation the same&lt;/b&gt;.  &lt;p&gt;That is a bit abstract. Let’s get more concrete. Suppose you have &lt;span class="code"&gt; &lt;p&gt;sealed class BankAccount&lt;br&gt;{ &lt;br&gt;&amp;nbsp; public decimal Balance { get; set; } &lt;/span&gt; &lt;p&gt;and somewhere in the class you have a calculation: &lt;span class="code"&gt; &lt;p&gt;&amp;nbsp; if (Balance &amp;gt; 0) … &lt;/span&gt; &lt;p&gt;Then one day you decide to change the semantics of Balance: &lt;span class="code"&gt; &lt;p&gt;sealed class BankAccount &lt;br&gt;{ &lt;br&gt;&amp;nbsp; private decimal balance; &lt;br&gt;&amp;nbsp; public decimal Balance &lt;br&gt;&amp;nbsp; { &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; get &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!CurrentUser.HasReadAccess(this))&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new SecurityException(); &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return balance;&lt;br&gt;… &lt;/span&gt; &lt;p&gt;OK, you’ve changed the semantics of Balance. Now, everywhere inside your class, &lt;i&gt;do you intend all calculations that at present use Balance to &lt;b&gt;have&lt;/b&gt; these security semantics, or do you intend them to &lt;b&gt;not have&lt;/b&gt; these security semantics?&lt;/i&gt;  &lt;p&gt;If the former, &lt;b&gt;keep the calling code the way it is; it is correct; changing it will introduce a bug.&lt;/b&gt;  &lt;p&gt;If the latter, &lt;b&gt;change it; it is now wrong; changing it will fix a bug.&lt;/b&gt;  &lt;p&gt;If the reason that you changed the property from automatic to explicit was NOT to modify the semantics then… then… then &lt;strong&gt;why on Earth did you change it?&lt;/strong&gt; And why are you contemplating making &lt;i&gt;further&lt;/i&gt; inessential changes?  &lt;p&gt;I presume that in this case there must be &lt;i&gt;some&lt;/i&gt; motivation for changing correct working code; if you have some motivation that is causing you to change correct, working&amp;nbsp; code, I suppose it can be applied equally well to all the other correct, working code in the class that calls that property.  &lt;blockquote&gt; &lt;p&gt;&lt;font color="#000080"&gt;User: Thanks. This is on my mind because I’m starting my first C# 3.0 project, and am experimenting with the new features. The scenario that tripped me up is exactly as you state; someone making a future semantic change. &lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Then your question is actually an instance of a more general question: &lt;strong&gt;“how do I future-proof a design?”&lt;/strong&gt; That is, how do I design and implement a class hierarchy now so that inevitable changes in the future are easier and less bug-prone? &lt;p&gt;That's a hard question, one which someone more knowledgeable than I am could write a whole book on. Next time on FAIC I'll give a few musings on this topic.&lt;/p&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9308211" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Code+Quality/default.aspx">Code Quality</category></item><item><title>Why Can't I Access A Protected Member From A Derived Class, Part Two: Why Can I?</title><link>http://blogs.msdn.com/ericlippert/archive/2008/03/28/why-can-t-i-access-a-protected-member-from-a-derived-class-part-two-why-can-i.aspx</link><pubDate>Sat, 29 Mar 2008 02:30:43 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8342569</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>36</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/8342569.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=8342569</wfw:commentRss><description>&lt;div class="mine"&gt; &lt;p&gt;This is a follow-up to &lt;a href="http://blogs.msdn.com/ericlippert/archive/2005/11/09/491031.aspx"&gt;my 2005 post on the same subject&lt;/a&gt;&amp;nbsp; which I believe sets a personal record for the longest time between parts of a series. (Of course, I didn't know it was a series when I started it.) Please read the previous article in this series, as this post assumes knowledge of part one.&lt;/p&gt; &lt;p&gt;.......&lt;/p&gt; &lt;p&gt;OK, now that you've read that, it's clear why you can only access a protected member from an instance of an object known to be of a type at least as derived as the current context. You can therefore deduce the answer to the question asked to me by a (very polite) reader this morning: &lt;strong&gt;Why did this code compile in C# 2.0 but give an error in C# 3.0?&lt;/strong&gt;&lt;/p&gt;&lt;span class="code"&gt; &lt;p&gt;public abstract class Item{&lt;br&gt;&amp;nbsp; private Item _parent;&lt;br&gt;&amp;nbsp; public Item Parent { &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return _parent; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected set { _parent = value; }&lt;br&gt;&amp;nbsp; }&lt;br&gt;}&lt;br&gt;public class Bag:Item{&lt;br&gt;&amp;nbsp; private List&amp;lt;Item&amp;gt; list = new List&amp;lt;Item&amp;gt;();&lt;br&gt;&amp;nbsp; public void Add(Item item)&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; item.Parent = this; // Error in C# 3.0&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; list.Add(item);&amp;nbsp; &lt;br&gt;&amp;nbsp; }&lt;br&gt;}&lt;br&gt;public class Torch : Item { }&lt;/p&gt;&lt;/span&gt; &lt;p&gt;It compiled in C# 2.0 because the compiler had a bug. We forgot to enforce the semantics of "protected" access for the property setter. Though the compiler did not generate an error, it did generate code which would not pass the CLR verification check! The code would run if it happened to be fully trusted, but it was not safe to do so. We fixed the bug in C# 3.0 and took the breaking change.&lt;/p&gt; &lt;p&gt;This raises a more interesting point though. Now that we correctly prevent you from setting the "parent" reference in this manner, how would you implement the desired pattern? The reader wanted the following conditions to be met:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;There are two kinds of items -- "leaf" items, and "container" items. Container items may contain either kind of item, so you could have a box containing a bag, which in turn contains a torch.  &lt;li&gt;An item may be in a container, and if it is, its parent reference refers to that container.  &lt;li&gt;These classes must be extensible by arbitrary third parties.  &lt;li&gt;"Unauthorized" code must not be able to muck around with the parenting invariants.&amp;nbsp; &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The reader was attempting to enforce these invariants by making the parent setter protected. But even in a world where it is legal to access a protected member from an arbitrary derived class, that does not ensure that the invariants are maintained! If you allow any derived class to muck with the parenting, then you are relying upon every third-party derived class to "play nicely" and maintain your invariant. If any of them are buggy or hostile, then who knows what can happen?&lt;/p&gt; &lt;p&gt;When I'm faced with this kind of problem, I try to go back to first principles. Considering each design constraint leads us to an implementation decision which implements that constraint:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;There are two kinds of abstract items -- items and containers. Therefore, there should be two abstract base classes, not just one.  &lt;li&gt;Containers are items. Therefore, the container class should derive from the item class.  &lt;li&gt;The parenting invariant must be maintained across all containers. Therefore the invariant implementation must be inside the abstract container base class.  &lt;li&gt;Every possible container requires "write" access to the parent state of every possible Item.&amp;nbsp; We want that access to be as restricted as possible. Ideally, we want it to be private. &lt;em&gt;The only by-design way to get access to a private is to be inside the class&lt;/em&gt;. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;And now a full solution becomes very straightforward:&lt;/p&gt;&lt;span class="code"&gt; &lt;p&gt;using System;&lt;br&gt;using System.Collections.Generic;&lt;br&gt;&lt;br&gt;public abstract class Item {&lt;br&gt;&amp;nbsp; public Item Parent { get; private set; }&lt;br&gt;&amp;nbsp; public abstract class Container : Item {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private HashSet&amp;lt;Item&amp;gt; items = new HashSet&amp;lt;Item&amp;gt;();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Add(Item item) {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (item.Parent != null)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new Exception("Item has inconsistent containment.");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; item.Parent = this;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; items.Add(item);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Remove(Item item) {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!Contains(item))&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new Exception("Container does not contain that item.");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; items.Remove(item);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; item.Parent = null;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public bool Contains(Item item) {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return items.Contains(item);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IEnumerable&amp;lt;Item&amp;gt; Items {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Do not just return items. Then the caller could cast it&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // to HashSet&amp;lt;Item&amp;gt; and then make modifications to your&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // internal state! Return a read-only sequence:&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach(Item item in items) yield return item;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp; }&lt;br&gt;}  &lt;p&gt;// These can be in third-party assemblies:&lt;br&gt;&lt;br&gt;public class Bag : Item.Container { }&lt;br&gt;public class Box : Item.Container { }&lt;br&gt;public class Torch : Item { }&lt;br&gt;public class TreasureMap : Item { }&lt;br&gt;&lt;br&gt;public class Program {&lt;br&gt;&amp;nbsp; public static void Main() {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var map = new TreasureMap();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var box = new Box();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; box.Add(map);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var bag = new Bag();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; bag.Add(box);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach(Item item in bag.Items) &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(item);&lt;br&gt;&amp;nbsp; }&lt;br&gt;}&lt;/p&gt;&lt;/span&gt; &lt;p&gt;Pretty slick eh?&lt;/p&gt; &lt;p&gt;A couple questions for you to ponder:&lt;/p&gt; &lt;p&gt;1) Suppose you were a hostile third party and you wanted to mess up the parenting invariant. Clearly, if you are sufficiently trusted, you can always use private reflection or unsafe code to muck around with the state directly, so that's not a very interesting attack. Any other bright ideas come to mind for ways that this code is vulnerable to tampering?&lt;/p&gt; &lt;p&gt;2) Suppose you wanted to make this hierarchy an immutable collection, where "Add" and "Remove" returned new collections rather than mutating the existing collection. How would you represent the parenting relationship?&lt;/p&gt; &lt;p&gt;Next time, another oddity involving "protected" semantics. Have a good weekend! &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8342569" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category></item><item><title>Covariance and Contravariance in C#, Part Nine: Breaking Changes</title><link>http://blogs.msdn.com/ericlippert/archive/2007/11/02/covariance-and-contravariance-in-c-part-nine-breaking-changes.aspx</link><pubDate>Fri, 02 Nov 2007 17:33:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5786612</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>34</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/5786612.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=5786612</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Today in the last entry in my ongoing saga of covariance and contravariance I’ll discuss what breaking changes adding this feature might cause.&lt;/P&gt;
&lt;P&gt;Simply adding variance awareness to the conversion rules should never cause any breaking change. However, the combination of adding variance to the conversion rules and making some types have variant parameters causes potential breaking changes.&lt;/P&gt;
&lt;P&gt;People are generally smart enough to not write:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;if (x is Animal) &lt;BR&gt;&amp;nbsp; DoSomething();&lt;BR&gt;else if (x is Giraffe) &lt;BR&gt;&amp;nbsp; DoSomethingElse(); // never runs&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;because the second condition is entirely subsumed by the first. But today in C# 3.0 it is entirely sensible to write&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;if (x is IEnumerable&amp;lt;Animal&amp;gt;) &lt;BR&gt;&amp;nbsp; DoSomething();&lt;BR&gt;else if (x is IEnumerable&amp;lt;Giraffe&amp;gt;) &lt;BR&gt;&amp;nbsp; DoSomethingElse();&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;because there did not used to be any conversion between &lt;SPAN class=code&gt;IEnumerable&amp;lt;Animal&amp;gt;&lt;/SPAN&gt; and &lt;SPAN class=code&gt;IEnumerable&amp;lt;Giraffe&amp;gt;&lt;/SPAN&gt;. If we turn on covariance in &lt;SPAN class=code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/SPAN&gt; and the compiled program containing the fragment uses the new library then its behaviour when given an &lt;SPAN class=code&gt;IEnumerable&amp;lt;Giraffe&amp;gt;&lt;/SPAN&gt; will change. The object will be assignable to &lt;SPAN class=code&gt;IEnumerable&amp;lt;Animal&amp;gt;&lt;/SPAN&gt;, and therefore the “&lt;SPAN class=code&gt;is&lt;/SPAN&gt;” will report “&lt;SPAN class=code&gt;true&lt;/SPAN&gt;”.&lt;/P&gt;
&lt;P&gt;There is also the issue of existing source code changing semantics or turning compiling programs into erroneous programs. For example, overload resolution may now fail where it used to succeed. If we have:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;interface IBar&amp;lt;T&amp;gt;{} // From some other assembly&lt;BR&gt;...&lt;BR&gt;void M(IBar&amp;lt;Tiger&amp;gt; x){}&lt;BR&gt;void M(IBar&amp;lt;Giraffe&amp;gt; x){}&lt;BR&gt;void M(object x) {}&lt;BR&gt;...&lt;BR&gt;IBar&amp;lt;Animal&amp;gt; y = whatever;&lt;BR&gt;M(y);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Then overload resolution picks the &lt;SPAN class=code&gt;object&lt;/SPAN&gt; version today because it is the sole applicable choice. If we change the definition of &lt;SPAN class=code&gt;IBar&lt;/SPAN&gt; to&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;interface IBar&amp;lt;-T&amp;gt;{} &lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;and recompile then we get an ambiguity error because now all three are applicable and there is no unique best choice.&lt;/P&gt;
&lt;P&gt;We always want to avoid breaking changes if possible, but sometimes new features are sufficiently compelling and the breaks are sufficiently rare that it’s worth it. My intuition is that by turning on interface and delegate variance we would enable many more interesting scenarios than we would break.&lt;/P&gt;
&lt;P&gt;What are your thoughts? Keep in mind that we expect that the vast majority of developers will never have to define the variance of a given type argument, but they may take advantage of variance frequently. Is it worth our while to invest time and energy in this sort of thing for a hypothetical future version of the language?&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5786612" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx">Covariance and Contravariance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_+4.0/default.aspx">C# 4.0</category></item><item><title>Future Breaking Changes, Part Three</title><link>http://blogs.msdn.com/ericlippert/archive/2007/09/04/future-breaking-changes-part-three.aspx</link><pubDate>Tue, 04 Sep 2007 17:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4653830</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>21</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/4653830.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=4653830</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;As I said &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/08/31/future-breaking-changes-part-two.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/08/31/future-breaking-changes-part-two.aspx"&gt;earlier&lt;/A&gt;, we hate causing breaking changes in our product, the C# compiler, because they cause our customers pain.&lt;/P&gt;
&lt;P&gt;Said customers are also software developers, and presumably they hate causing breaking changes for their customers as much as we do. We want to throw our customers into the &lt;A class="" href="http://www.codinghorror.com/blog/archives/000940.html" mce_href="http://www.codinghorror.com/blog/archives/000940.html"&gt;Pit of Success&lt;/A&gt; and give them tools which encourage them where possible to prevent breaking changes. This leads to some subtle issues in language design.&lt;/P&gt;
&lt;P&gt;Pop quiz. What does this program do?&lt;/P&gt;
&lt;HR&gt;
&lt;SPAN class=code&gt;// Alpha.DLL&lt;BR&gt;namespace Alpha {&lt;BR&gt;&amp;nbsp; public class Charlie {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Frob(int i) { System.Console.WriteLine("int"); }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // etc.&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;} 
&lt;HR&gt;
// Bravo.EXE, references Alpha.DLL.&lt;BR&gt;namespace Bravo {&lt;BR&gt;&amp;nbsp; public class Delta : Alpha.Charlie {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Frob(float f) { System.Console.WriteLine("float"); }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // etc.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void Main() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Delta d = new Delta();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; d.Frob(1);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;} 
&lt;HR&gt;
&lt;/SPAN&gt;
&lt;P&gt;Most people look at this program and say “clearly &lt;SPAN class=code&gt;Charlie.Frob(int)&lt;/SPAN&gt; is the best possible match for the call, so that is called.” A compelling argument, but wrong. As the standard says, “methods in a base class are not candidates if any method in a derived class is applicable". &lt;/P&gt;
&lt;P&gt;In other words, the overload resolution algorithm starts by searching the class for an applicable method. If it finds one then all the other applicable methods in deeper base classes are removed from the candidate set for overload resolution. Since &lt;SPAN class=code&gt;Delta.Frob(float)&lt;/SPAN&gt; is applicable, &lt;SPAN class=code&gt;Charlie.Frob(int)&lt;/SPAN&gt; is never even considered as a candidate. Only if no applicable candidates are found in the most derived type do we start looking at its base class.&lt;/P&gt;
&lt;P&gt;Why on earth would we do that? Clearly in this example the base class member is the far better match, so why wouldn’t we even consider it?&lt;/P&gt;
&lt;P&gt;It is instructive to consider what happens in a world where we do implement the rule “pick the best applicable candidate from any base”. Suppose we did that. &lt;/P&gt;
&lt;P&gt;In the previous version of Alpha.DLL, &lt;SPAN class=code&gt;Charlie&lt;/SPAN&gt; did not have a method &lt;SPAN class=code&gt;Frob(int)&lt;/SPAN&gt;.; When Bravo Corporation wrote Bravo.EXE, every call inside class &lt;SPAN class=code&gt;Delta&lt;/SPAN&gt; to method &lt;SPAN class=code&gt;Frob&lt;/SPAN&gt; was a call to &lt;SPAN class=code&gt;Delta.Frob(float)&lt;/SPAN&gt;. Then one day Alpha corporation did customer research and discovered that a lot of their customers like to frob integers. They added this feature in their latest version. Delta corporation gets the new version of Alpha.DLL, recompiles Bravo.EXE, and suddenly their carefully developed code is sometimes calling a method that they didn’t write, which does something subtly incompatible with their implementation. &lt;/P&gt;
&lt;P&gt;Alpha corporation has just pushed a breaking change onto Bravo corporation, which, if they don’t catch it in time, may now be pushing a subtly broken version onto their customers in turn, and hey! we’re in the Pit of Despair again!&lt;/P&gt;
&lt;P&gt;This particular family of breaking changes is called the "brittle base class problem"; there are many versions of it and &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2004/01/07/48399.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2004/01/07/48399.aspx"&gt;different languages deal with it in different ways.&lt;/A&gt; Lots of work went into the design of C# to try and make it harder for people to accidentally cause brittle base class problems. That is why we make you distinguish between the&amp;nbsp;original definition of a virtual method and an overriding method. That is why we make you put “new” on methods which shadow other methods. All these semantics are in part to help prevent, mitigate or diagnose brittle base class issues and thereby prevent accidental breaking changes in C# code.&lt;/P&gt;
&lt;P&gt;Next time on FAIC: some psychic debugging. Then a bit later I want to talk more about breaking changes, this time in the context of thinking about covariance and contravariance.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4653830" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Brittle+Base+Classes/default.aspx">Brittle Base Classes</category></item><item><title>Future Breaking Changes, Part Two</title><link>http://blogs.msdn.com/ericlippert/archive/2007/08/31/future-breaking-changes-part-two.aspx</link><pubDate>Fri, 31 Aug 2007 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4649198</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/4649198.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=4649198</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;&lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/08/30/future-breaking-changes-part-one.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/08/30/future-breaking-changes-part-one.aspx"&gt;Last time&lt;/A&gt; I mentioned that one of the subtleties of programming language design is weighing the benefit of adding a feature against the pain it will cause you in the future. This is a specific&amp;nbsp;subset of a more general set of problems. Languages run into the same problem that other large, multiply-versioned software products run into; if you have n existing features and want to add m new features, then you have at least m x n possible interactions to consider. In an ideal world the features would all be &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2005/10/28/483905.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2005/10/28/483905.aspx"&gt;orthogonal&lt;/A&gt; to each other, but in reality of course new features modify the behaviour of existing features. &lt;/P&gt;
&lt;P&gt;Just as a random example, what on earth do &lt;A class="" href="http://blogs.msdn.com/wesdyer/archive/2007/05/23/in-case-you-haven-t-heard.aspx" mce_href="http://blogs.msdn.com/wesdyer/archive/2007/05/23/in-case-you-haven-t-heard.aspx"&gt;partial methods&lt;/A&gt; have to do with &lt;A class="" href="http://www.interact-sw.co.uk/iangblog/2005/09/30/expressiontrees" mce_href="http://www.interact-sw.co.uk/iangblog/2005/09/30/expressiontrees"&gt;expression trees&lt;/A&gt;? Both are new features for C# 3.0, but other than that, they seem to have nothing to do with each other. But what happens when you have an expression tree lambda which contains &lt;EM&gt;a call to a partial method which is going to be removed&lt;/EM&gt;? This interaction has to be carefully defined. &lt;EM&gt;Every interaction between every feature has to be carefully defined&lt;/EM&gt;, and the larger the area of the feature interaction is, the more likely it is that there will be unfortunate consequences of this nonorthogonality, such as breaking changes.&lt;/P&gt;
&lt;P&gt;I said last time that implicitly typed&amp;nbsp;lambdas are just such a feature -- big surface area of nonorthogonal interactions which will lead to future breaking changes. I'd like to explore that in more detail, because it might not be immediately obvious why that is the case.&lt;/P&gt;
&lt;P&gt;The rule for determining whether an &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/01/10/lambda-expressions-vs-anonymous-methods-part-one.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/01/10/lambda-expressions-vs-anonymous-methods-part-one.aspx"&gt;implicitly typed lambda&lt;/A&gt; is convertible to a given delegate type is (somewhat simplified) “If possible, infer the return type and the types of the lambda parameters from the delegate type. Try to&amp;nbsp;bind the lambda with those types. If the inference and&amp;nbsp;binding succeeds&amp;nbsp;with no errors&amp;nbsp;then the lambda expression is convertible to that delegate type.” &lt;/P&gt;
&lt;P&gt;For example, if we had a lambda expression like &lt;SPAN class=code&gt;x=&amp;gt;x - 123.4&lt;/SPAN&gt;, that would be convertible to &lt;SPAN class=code&gt;&lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2006/06/21/641831.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2006/06/21/641831.aspx"&gt;Func&amp;lt;double, double&amp;gt;&lt;/A&gt;&lt;/SPAN&gt; but not to &lt;SPAN class=code&gt;Func&amp;lt;string, double&amp;gt;&lt;/SPAN&gt; (because the subtraction cannot be legally bound) or &lt;SPAN class=code&gt;Func&amp;lt;double, int&amp;gt;&lt;/SPAN&gt; (because&amp;nbsp;the conversion to the return type cannot be bound).&lt;/P&gt;
&lt;P&gt;Notice how the overlap between this new feature – implicitly typed lambda convertibility to a delegate type – overlaps with&amp;nbsp;almost every other feature&amp;nbsp;in the entire C# language. Consider the impact of this design decision on the potential for breaking changes in the future. &lt;EM&gt;Every single time we make a change to the rules for how the body of a method is bound, we are potentially changing whether a given lambda expression is convertible to a given type.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;Now, is that really so bad? Generally when we make changes to the method body binding rules, we do so in as non-breaking a manner as possible. We should never be making an existing lambda that &lt;EM&gt;does&lt;/EM&gt; convert suddenly &lt;EM&gt;stop&lt;/EM&gt; converting, because then we would also be breaking compilation of the equivalent &lt;EM&gt;nominal&lt;/EM&gt; method body. Really we should only be causing presently-erroneous code to suddenly start being non-erroneous, and as we’ve already discussed, that’s not a breaking change.&lt;/P&gt;
&lt;P&gt;Or is it?&lt;/P&gt;
&lt;P&gt;Actually, now in a lot of cases it could be.&lt;/P&gt;
&lt;P&gt;Consider a silly example. Suppose we decide that in some hypothetical C# 4.0(‡) language it should be legal to subtract a double from a string. That’s not entirely farfetched – that’s perfectly legal in JScript. You just convert the&amp;nbsp;string to a number&amp;nbsp;and subtract. We might reason that this new feature is not a breaking change, because no program that ever&amp;nbsp;subtracted a double from a string&amp;nbsp;ever compiled before. But it &lt;EM&gt;is&lt;/EM&gt; a breaking change, because now &lt;EM&gt;this&lt;/EM&gt; program stops compiling:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;using System;&lt;BR&gt;class Program {&lt;BR&gt;&amp;nbsp; void M(Func&amp;lt;double, int&amp;gt; f){}&lt;BR&gt;&amp;nbsp; void M(Func&amp;lt;string, double&amp;gt; f){}&lt;BR&gt;&amp;nbsp; void M(Func&amp;lt;double, double&amp;gt; f){}&lt;BR&gt;&amp;nbsp; static void Main() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; M(x=&amp;gt;x-123.4);&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Before the change, the program unambiguously chooses the third overload. But with our change to addition semantics, now the second and third overloads would both work. Neither would be clearly better than the other. The compiler would then give an ambiguity error. Thus, this is a breaking change. &lt;/P&gt;
&lt;P&gt;It gets even worse; with some cleverness we could come up with more subtle breaking changes, where the compiler would not produce an error but instead would choose a &lt;EM&gt;different&lt;/EM&gt; overload than before. At least a program which fails to compile calls attention to the problem; recompiling and having the behaviour change subtly might go unnoticed for a long time.&lt;/P&gt;
&lt;P&gt;This is a general problem with overload resolution: it depends upon conversion semantics. If we make the conversion semantics more strict then it is possible to go from having exactly one overload which works to zero, which is a breaking change. If we make the conversion semantics less strict then it is possible to go from having exactly one overload which works to two, which is also (usually) a breaking change.&lt;/P&gt;
&lt;P&gt;Since lambda convertibility depends on every other language rule for binding an expression, any change to &lt;EM&gt;any&lt;/EM&gt; of those rules is a potential change in convertibility, and hence a potential breaking change for overload resolution. Now, hopefully few real-world codebases will end up in the above situation, where a method is overloaded solely on a bunch of different delegate types, but still, I worry. We think implicitly typed lambdas are worth it, but this was a tough call that we agonized over for a long time.&lt;/P&gt;
&lt;P&gt;Next time on FAIC: More on subtle language design issues involving breaking changes. Have a pleasant Labour Day weekend, Canadian and American readers!&lt;/P&gt;
&lt;HR&gt;

&lt;P&gt;(‡) I call out that this is the &lt;EM&gt;hypothetical&lt;/EM&gt; C# 4.0 compiler because of course I do not discuss the feature set of unannounced and non-existing products on public blogs. &lt;BR&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4649198" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Overload+Resolution/default.aspx">Overload Resolution</category></item><item><title>Future Breaking Changes, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2007/08/30/future-breaking-changes-part-one.aspx</link><pubDate>Thu, 30 Aug 2007 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4634821</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>14</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/4634821.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=4634821</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;We on the C# team hate making breaking changes.&lt;/P&gt;
&lt;P&gt;As my colleague Neal called out in &lt;A class="" href="http://blogs.msdn.com/nealho/archive/2005/11/22/496101.aspx" mce_href="http://blogs.msdn.com/nealho/archive/2005/11/22/496101.aspx"&gt;his article on the subject from a couple years ago&lt;/A&gt;, by “breaking change” we mean a change in the compiler behaviour which causes an existing program to either stop compiling entirely, or start behaving differently when recompiled. We hate them because they can cause&amp;nbsp;intense customer pain, and are therefore barriers to upgrading. We work hard on improving the quality of the C# toolset every day and want our customers to gain the benefits of upgrading; they cannot do that if doing so causes&amp;nbsp;more pain than the new features are worth.&lt;/P&gt;
&lt;P&gt;Which is not to say that we do not make breaking changes occasionally. We do. But in those circumstances where we have to, we try to mitigate the pain as much as possible. For example:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;We try to ensure that breaking changes only affect unusual corners of the language which real production code is unlikely to hit.&lt;/LI&gt;
&lt;LI&gt;When we do cause breaking changes, we sometimes introduce heuristics and warnings which detect the situation and warn the developer.&lt;/LI&gt;
&lt;LI&gt;If possible, breaking changes should move the implementation into compliance with the published standard. (Often breaking changes are a result of fixing a compliance bug.)&lt;/LI&gt;
&lt;LI&gt;We try to communicate the reasoning behind a breaking change crisply and succinctly.&lt;/LI&gt;
&lt;LI&gt;And so on.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;I could write a whole series of blog articles about specific breaking changes – and in fact, I have done so many times over the years. (For example, &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2004/06/10/152831.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2004/06/10/152831.aspx"&gt;here&lt;/A&gt;, &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2005/10/19/482796.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2005/10/19/482796.aspx"&gt;here&lt;/A&gt;, &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2006/04/06/570126.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2006/04/06/570126.aspx"&gt;here&lt;/A&gt;, &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2006/05/24/606278.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2006/05/24/606278.aspx"&gt;here&lt;/A&gt; and &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/04/16/chained-user-defined-explicit-conversions-in-c.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/04/16/chained-user-defined-explicit-conversions-in-c.aspx"&gt;here&lt;/A&gt;.)&lt;/P&gt;
&lt;P&gt;Given that we hate breaking changes, clearly we want to ensure that &lt;EM&gt;as we add new features to the C# language we do not break existing features&lt;/EM&gt;. &lt;A class="" href="http://blogs.msdn.com/ericgu/archive/2004/01/12/57985.aspx" mce_href="http://blogs.msdn.com/ericgu/archive/2004/01/12/57985.aspx"&gt;New features start out with points against them and have to justify their benefits&lt;/A&gt;. If the feature is a breaking change, that is hugely more points against it. &lt;/P&gt;
&lt;P&gt;For example, adding generics to C# 2.0 was a breaking change. This program, legal in C# 1.0, no longer compiles:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;class Program&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static void M(bool x, bool y) {}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static void Main() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int N = 1, T = 2, U = 3, a = 4, b = 5;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; M(N &amp;lt; T, U &amp;gt; (a+b));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;because we now think that N is a generic method of one argument. But the compelling benefit of generics greatly outweighed the pain of this rather contrived example, so we took the breaking change. (And &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2006/07/07/659259.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2006/07/07/659259.aspx"&gt;the error message now produced diagnoses the problem&lt;/A&gt;.)&lt;/P&gt;
&lt;P&gt;But what I want to talk about in this set of articles is something a bit more subtle than these specific breaking changes. &lt;/P&gt;
&lt;P&gt;Given that we hate breaking changes, we want to ensure that as we add new features to the C# language &lt;EM&gt;we are not setting ourselves up to have to make breaking changes in the future&lt;/EM&gt;. If we are, then the feature needs to be justified against not only any breaking changes it is &lt;EM&gt;presently&lt;/EM&gt; introducing, but also against the &lt;EM&gt;potential&lt;/EM&gt; for breaking changes in the future. &lt;EM&gt;We do not want to introduce a new feature that makes it harder for us to introduce entirely different features in the future unless the proposed new feature is really great.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/01/10/lambda-expressions-vs-anonymous-methods-part-one.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/01/10/lambda-expressions-vs-anonymous-methods-part-one.aspx"&gt;Implicitly typed lambdas&lt;/A&gt; are an example of a feature which will cause us innumerable breaking change headaches in the future, but we believe that&amp;nbsp;the compelling user benefit of them is so high (and the breaks are sufficiently isolated to corner cases) that we are willing to take that pain.&lt;/P&gt;
&lt;P&gt;Next time on FAIC, I’ll describe in detail how it is that implicitly typed lambdas are going to make it harder to get new features into the C# type system because of potential breaking changes.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4634821" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category></item><item><title>Chained user-defined explicit conversions in C#</title><link>http://blogs.msdn.com/ericlippert/archive/2007/04/16/chained-user-defined-explicit-conversions-in-c.aspx</link><pubDate>Mon, 16 Apr 2007 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2102398</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/2102398.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=2102398</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Reader Niall asked me why the following code compiles but produces an exception at runtime:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;class Base {}&lt;BR&gt;class Derived : Base {}&lt;BR&gt;class Castable {&lt;BR&gt;&amp;nbsp;&amp;nbsp;public static explicit operator Base() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return new Base();&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&lt;BR&gt;// ...&lt;BR&gt;Derived d = (Derived)(new Castable());&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;It should be clear why this produces an exception at runtime; the user-defined operator returns a &lt;SPAN class=code&gt;Base&lt;/SPAN&gt; and that is not assignable to a variable of type &lt;SPAN class=code&gt;Derived&lt;/SPAN&gt;. But why does the compiler allow it in the first place?&lt;/P&gt;
&lt;P&gt;First off, let’s define the difference between an implicit and an explicit conversion. An implicit conversion is one which the compiler knows can always be done without incurring the risk of a runtime exception. When you have a method &lt;SPAN class=code&gt;int Foo(int i){...}&lt;/SPAN&gt; and call it with &lt;SPAN class=code&gt;long l = Foo(myshort);&lt;/SPAN&gt;, the compiler inserts implicit conversions from &lt;SPAN class=code&gt;int&lt;/SPAN&gt; to &lt;SPAN class=code&gt;long &lt;/SPAN&gt;on the return side and from &lt;SPAN class=code&gt;short&lt;/SPAN&gt; to &lt;SPAN class=code&gt;int&lt;/SPAN&gt; on the call side. There is no &lt;SPAN class=code&gt;int &lt;/SPAN&gt;which doesn’t fit into a &lt;SPAN class=code&gt;long &lt;/SPAN&gt;and there is no &lt;SPAN class=code&gt;short&lt;/SPAN&gt; which doesn’t fit into an &lt;SPAN class=code&gt;int&lt;/SPAN&gt;, so we know that the conversions will always succeed, so we just up and do them for you.&lt;/P&gt;
&lt;P&gt;There are also conversions which we know at compile time will never succeed. If there is no user-defined conversion from &lt;SPAN class=code&gt;Giraffe&lt;/SPAN&gt; to &lt;SPAN class=code&gt;int&lt;/SPAN&gt;, then &lt;SPAN class=code&gt;Foo(new Giraffe())&lt;/SPAN&gt; is always going to fail at runtime, so this fails at compile time.&lt;/P&gt;
&lt;P&gt;An explicit conversion is a conversion which might succeed sometimes but might also fail. We cannot disallow it, because it might succeed, but we can’t go silently inserting one either, since it might fail unexpectedly. We need to force the developer to acknowledge that risk explicitly. If you called &lt;SPAN class=code&gt;ulong ul = Foo(mynullableint);&lt;/SPAN&gt; then that might fail, so the compiler requires you to spell out that the conversions are explicit. The assignment could be written &lt;SPAN class=code&gt;ulong ul = (ulong)Foo((int)mynullableint);&lt;/SPAN&gt;.&lt;/P&gt;
&lt;P&gt;There are two times that the compiler will insert an explicit cast for you without producing a warning or error. The first is the case above. When a user-defined explicit cast requires an explicit conversion on either the call side or the return side, the compiler will insert the explicit conversions as needed. The compiler figures that if the developer put the explicit cast in the code in the first place then the developer knew what they were doing and took the risk that any of the conversions might fail. That’s what the cast means: this conversion might fail, I will deal with it.&lt;/P&gt;
&lt;P&gt;I understand that this puts a burden upon the developer to fully understand the implications of a cast, but the alternative is to make you spell it out even further, and it just gets to be too much. The logical extreme of this would be a case such as&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;public struct S{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static explicit operator decimal?(S s) {return 1.0m;}&lt;BR&gt;}&lt;BR&gt;//...&lt;BR&gt;S? s = new S();&lt;BR&gt;int i = (int) s;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Here we do first an explicit conversion from &lt;SPAN class=code&gt;S?&lt;/SPAN&gt; to &lt;SPAN class=code&gt;S&lt;/SPAN&gt;, then a user-defined explicit conversion from &lt;SPAN class=code&gt;S&lt;/SPAN&gt; to &lt;SPAN class=code&gt;decimal?&lt;/SPAN&gt;, then an explicit conversion from &lt;SPAN class=code&gt;decimal?&lt;/SPAN&gt; to &lt;SPAN class=code&gt;decimal&lt;/SPAN&gt;, and then an explicit conversion from &lt;SPAN class=code&gt;decimal&lt;/SPAN&gt; to &lt;SPAN class=code&gt;int&lt;/SPAN&gt;. That’s four explicit conversions for the price of one cast, which I think is pretty good value for your money.&lt;/P&gt;
&lt;P&gt;I want to note at this point that this is as long as the chain gets. A user-defined conversion can have built-in conversions inserted automatically on the call and return sides, but we never automatically insert other user-defined conversions. We never say that there’s a user-defined conversion from &lt;SPAN class=code&gt;Alpha&lt;/SPAN&gt; to &lt;SPAN class=code&gt;Bravo&lt;/SPAN&gt;, and a user-defined conversion from &lt;SPAN class=code&gt;Bravo&lt;/SPAN&gt; to &lt;SPAN class=code&gt;Charlie&lt;/SPAN&gt;, and therefore casting an &lt;SPAN class=code&gt;Alpha&lt;/SPAN&gt; to a &lt;SPAN class=code&gt;Charlie&lt;/SPAN&gt; is legal. That doesn’t fly.&lt;/P&gt;
&lt;P&gt;And a built-in conversion can be lifted to nullable, which may introduce additional conversions as in the case above. But again, these are never user-defined.&lt;/P&gt;
&lt;P&gt;The second is in the &lt;SPAN class=code&gt;foreach&lt;/SPAN&gt; loop. If you have &lt;SPAN class=code&gt;foreach(Giraffe g in myAnimals)&lt;/SPAN&gt; then we generate code which fetches each member of the collection and does an “explicit” conversion to &lt;SPAN class=code&gt;Giraffe&lt;/SPAN&gt;. If there happens to be a &lt;SPAN class=code&gt;Snail&lt;/SPAN&gt; or a &lt;SPAN class=code&gt;WaterBuffalo&lt;/SPAN&gt; in &lt;SPAN class=code&gt;myAnimals&lt;/SPAN&gt;, that’s a runtime exception. I considered adding a warning to the compiler for this case to say hey, be aware that your collection is of a more general type, this could fail at runtime. It turns out that there are so many programs which use this programming style, and so many of them have “compile with warnings as errors” turned on in their builds, that this would be a huge breaking change. So we opted to not do it.&lt;/P&gt;&lt;/DIV&gt;&lt;/SPAN&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2102398" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Conversions/default.aspx">Conversions</category></item><item><title>Odious ambiguous overloads, part two</title><link>http://blogs.msdn.com/ericlippert/archive/2006/04/06/odious-ambiguous-overloads-part-two.aspx</link><pubDate>Thu, 06 Apr 2006 20:13:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:570126</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/570126.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=570126</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;There were a number of ideas in the comments for what &lt;A href="http://blogs.msdn.com/ericlippert/archive/2006/04/05/569085.aspx"&gt;we should do about the unfortunate situation I described yesterday&lt;/A&gt;. We considered all of these options and more.&amp;nbsp; I thought I might talk a bit about the pros and cons of each.&lt;/P&gt;
&lt;P&gt;I suggested &lt;STRONG&gt;do nothing&lt;/STRONG&gt;.&amp;nbsp; We shipped with this behaviour in C# 2.0, the world didn't come to an end, we can keep on shipping with it. The pro side is that this is the cheapest and easiest thing to do.&amp;nbsp; The con side is that as a reader pointed out, this is a gross "gotcha" just waiting for someone to stumble upon it.&lt;/P&gt;
&lt;P&gt;DrPizza suggested that we &lt;STRONG&gt;come up with a syntax&lt;/STRONG&gt; that disambiguates between the two ambiguous cases.&amp;nbsp; On the pro side, the problem would be clearly solved.&amp;nbsp; On the con side, this might be a breaking change (because suddenly one of the methods that used to bind one way might start binding the other way, depending on what the choice of syntax was.)&lt;/P&gt;
&lt;P&gt;Also on the con side, adding new language syntax is something that we do not do lightly.&amp;nbsp; There is considerable work involved in changing the specification, and this is kind of an edge case.&lt;/P&gt;
&lt;P&gt;Ayende Rahien suggested that we &lt;STRONG&gt;add an attribute&lt;/STRONG&gt; that hints to the compiler which is the right binding. This has the nice property of not introducing new language syntax, but is kind of ugly.&lt;/P&gt;
&lt;P&gt;These are both good ideas but unfortunately, as it turns out, neither of these work for technical reasons which I will go into in detail below.&lt;/P&gt;
&lt;P&gt;Chris D suggested that &lt;STRONG&gt;the constructed interface should be treated as an interface with only one method&lt;/STRONG&gt;. That's a really nice idea, but unfortunately it doesn't work with the CLR definition of generics.&amp;nbsp; An interface with n methods has n vtable slots that need filling, period, and n is invariant under construction. We'd have to change both the semantics of constructed interfaces and their implementation in the CLR, which means changing both the C# spec and the CLR spec, and that's way too much work for this edge case.&lt;/P&gt;
&lt;P&gt;Kyle Lahnakoski suggested that it &lt;STRONG&gt;simply be an error&lt;/STRONG&gt;.&amp;nbsp; There are several ways this could be an error.&lt;/P&gt;
&lt;P&gt;It could be an error to have an unconstructed generic type which could &lt;EM&gt;possibly&lt;/EM&gt; be constructed to produce a duplicated signature.&amp;nbsp; This was how generics originally worked in C#, but we decided that we could allow these cases and we can't really go back on that decision now – that would be a huge breaking change. There are many serializable generic objects which use a pattern of having a method that takes a type parameter to overload a method that takes a serialization object parameter, and all of those would suddenly be errors.&lt;/P&gt;
&lt;P&gt;It could be an error to construct a generic type so as to &lt;EM&gt;actually&lt;/EM&gt;&amp;nbsp;produce a duplicate signature, but again, we decided to allow&amp;nbsp;that in C# 2.0&amp;nbsp;and it would be a large breaking change to go back now.&lt;/P&gt;
&lt;P&gt;It could be an error to have any explicit implementation of an interface method which matches ambiguously.&amp;nbsp; This would be a smaller breaking change, but still breaking.&lt;/P&gt;
&lt;P&gt;What do any of these breaking changes buy the user though?&amp;nbsp; Not more functionality, but less.&amp;nbsp; Basically we'd be saying "you could do this before, and now you can't, too bad." That's a hard sell.&lt;/P&gt;
&lt;P&gt;Carlos suggested unification – that is, &lt;STRONG&gt;have an explicit implementation map to every method that it matches, not just the first one&lt;/STRONG&gt;.&amp;nbsp; This is a breaking change, but it seems like the most natural thing to do.&amp;nbsp; Since an implicit implementation maps to every interface slot that it matches, why shouldn't an explicit implementation do the same? This means adding new language to the spec, but no new syntax.&lt;/P&gt;
&lt;P&gt;This is what we decided to do, and I tried to implement it, only to discover that, uh, actually that stuff I told you yesterday about the implicit implementation matching the first one in source code order is a bit of a mistruth. That's what I thought when I first looked at the problem, but upon closer examination, something deeper was wrong.&lt;/P&gt;
&lt;P&gt;In fact what is going on here is that when the CLR loads the class for the first time, it does a verification check to ensure that the class does in fact implement every method of every interface that it says it does.&amp;nbsp; It is the CLR, not C#, which matches the explicit implementation to the first matching slot in the constructed interface type! It just so happens that since metadata for the interface is emitted in source-code order, that the CLR appears to do the match in source code order.&amp;nbsp; It actually does it in a CLR-implementation-defined order that just happens to be source code order.&lt;/P&gt;
&lt;P&gt;To understand why we can't fix this, you need to understand how&amp;nbsp;explicit implementations are represented in metadata.&amp;nbsp; In the CLR metadata for a class there is a table called the MethodImpl table which says "method blah of class foo explicitly implements method bar of interface IFred".&amp;nbsp; The "method bar of interface IFred" portion of that mapping may be either a token to a method of the unconstructed interface (a "MethodDef")&amp;nbsp;, or it may be a token representing a method on the constructed interface (a "MemberRef").&lt;/P&gt;
&lt;P&gt;We can't use a MethodDef because there is a signature mismatch between the class's implementation and the method on the unconstructed interface.&amp;nbsp; One takes an int, the other takes a type parameter, and the CLR&amp;nbsp;flags that as illegal. So that's out.&lt;/P&gt;
&lt;P&gt;But we can't use the latter because the&amp;nbsp;MemberRef identifies the constructed interface&amp;nbsp;method&amp;nbsp;by – you guessed it – its signature!&amp;nbsp; And now we're in the same hideous bind all over again.&amp;nbsp; We have no way to tell the CLR "&lt;EM&gt;no, really, use the generic-substituted version of the method"&lt;/EM&gt;, because &lt;STRONG&gt;it can't tell the two signatures apart either&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;To fix this problem by either unifying, or adding a syntax/attribute to disambiguate, we need some way to represent that unification/disambiguation in metadata. But&amp;nbsp;the CLR simply lacks the concept of "method token for constructed method identified by something more unique than signature".&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Though we can certainly suggest that this is a weakness in the CLR metadata design, waiting around for that to be addressed to fix this edge-case problem seems like a non-starter. Given that we can't fix it in the current CLR the way we'd like, and making it an error seems like an egregious overreaction that buys the user nothing, but at the same time doing nothing is leaving a gotcha in the code waiting to happen, I took the only course of action left:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;Warning: Explicit interface implementation 'I1&amp;lt;int&amp;gt;.M(int)' matches more than one interface member. Which interface member&amp;nbsp;is actually chosen is implementation-dependent. Consider using a non-explicit implementation instead."&amp;nbsp; &lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Unfortunately, sometimes that's the best you can do.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=570126" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category></item><item><title>Odious ambiguous overloads, part one</title><link>http://blogs.msdn.com/ericlippert/archive/2006/04/05/odious-ambiguous-overloads-part-one.aspx</link><pubDate>Wed, 05 Apr 2006 18:58:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:569085</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/569085.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=569085</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;As you might have gathered, a lot of the decisions we have to make day-to-day here involve potential breaking changes on odd edge cases. Here's another one. &lt;/P&gt;
&lt;P&gt;Consider the following terrible but legal code:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;public interface I1&amp;lt;U&amp;gt; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void M(U i);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void M(int i);&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;My&amp;nbsp;intense pain begins when the user writes:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;public class C1 : I1&amp;lt;int&amp;gt; {&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;In the early version of the C# specification it was actually illegal to have an ambiguity like this, but the spec was changed so that when doing overload resolution on a call to &lt;SPAN class=code&gt;M&lt;/SPAN&gt; we can choose one, according to section 14.4.2.2:&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;If one [argument type] is non-generic, but the other is generic, then the non-generic is better. &lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;But still, as you will soon see, we're in a world of hurt for another reason, namely that&amp;nbsp;this class must now implement both &lt;SPAN class=code&gt;M(int i)&lt;/SPAN&gt; and, uh, &lt;SPAN class=code&gt;M(int i)&lt;/SPAN&gt;.&amp;nbsp;Fortunately, a nonexplicit implementation binds to both methods, so this works just fine:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;public class C1 : I1&amp;lt;int&amp;gt; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void M(int i) { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("class " + i); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;The method implements both versions of &lt;SPAN class=code&gt;M&lt;/SPAN&gt; and the contract is satisfied.&amp;nbsp; But we have problems if we try to do an explicit interface implementation:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;public class C2 : I1&amp;lt;int&amp;gt; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void I1&amp;lt;int&amp;gt;.M(int i) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("explicit " + i);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Does this explicitly implement both members of &lt;SPAN class=code&gt;I1&lt;/SPAN&gt;?&amp;nbsp; Or just one?&amp;nbsp; If so, which one?&lt;/P&gt;
&lt;P&gt;In the current compiler this code produces a terrible, terrible error:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;error CS0535: 'C2' does not implement interface member 'I1&amp;lt;int&amp;gt;.M(int)'&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Is that so?&amp;nbsp; It sure looks like it implements it!&lt;/P&gt;
&lt;P&gt;What happens when we have both an explicit implementation and a class implementation?&amp;nbsp; &lt;STRONG&gt;The spec does not actually say what to do.&lt;/STRONG&gt; It turns out that we end up in a situation where runtime behaviour depends on &lt;STRONG&gt;source code order&lt;/STRONG&gt; of the interface! Check this out:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;public interface I1&amp;lt;U&amp;gt; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void M(U i); // generic first&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void M(int i);&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;public interface I2&amp;lt;U&amp;gt; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void M(int i);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void M(U i); // generic second&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;public class C3: I1&amp;lt;int&amp;gt;, I2&amp;lt;int&amp;gt; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void I1&amp;lt;int&amp;gt;.M(int i) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("c3 explicit I1 " + i);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void I2&amp;lt;int&amp;gt;.M(int i) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("c3 explicit I2 " + i);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void M(int i) { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("c3 class " + i); &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;class Test {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static void Main() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; C3 c3 = new C3();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; I1&amp;lt;int&amp;gt; i1_c3 = c3;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; I2&amp;lt;int&amp;gt; i2_c3 = c3;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; i1_c3.M(101);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; i2_c3.M(102);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;What happens here is that the explicit interface implementation mappings in the class match the methods in the interfaces in a first-come-first-served manner:&lt;/P&gt;
&lt;P&gt;&lt;SPAN class=code&gt;void I1&amp;lt;int&amp;gt;.M(U)&lt;/SPAN&gt; maps to explicit implementation &lt;SPAN class=code&gt;void I1&amp;lt;int&amp;gt;.M(int i)&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN class=code&gt;void I1&amp;lt;int&amp;gt;.M(int)&lt;/SPAN&gt; maps to implicit implementation &lt;SPAN class=code&gt;public void M(int i)&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN class=code&gt;void I2&amp;lt;int&amp;gt;.M(int)&lt;/SPAN&gt; maps to explicit implementation &lt;SPAN class=code&gt;void I2&amp;lt;int&amp;gt;.M(int i)&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN class=code&gt;void I2&amp;lt;int&amp;gt;.M(U)&lt;/SPAN&gt; maps to implicit implementation &lt;SPAN class=code&gt;public void M(int i)&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Then (because of the aforementioned section 14.4.2.2) when we see&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; i1_c3.M(101);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; i2_c3.M(102);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;we prefer the typed-as-int versions to the generic substitution versions, so this program calls the two non-generic versions and produces the output:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;c3 class 101&lt;BR&gt;c3 explicit I2 102&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;And as you'd expect,&amp;nbsp;if we force the compiler to pick the generic versions then we get similar behaviour:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;static void Main() {&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;C3 c3 = new C3();&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;Thunk1&amp;lt;int&amp;gt;(c3,103);&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;Thunk2&amp;lt;int&amp;gt;(c3, 104);&lt;BR&gt;}&lt;BR&gt;static void Thunk1&amp;lt;U&amp;gt;(I1&amp;lt;U&amp;gt; i1, U u) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; i1.M(u);&lt;BR&gt;}&lt;BR&gt;static void Thunk2&amp;lt;U&amp;gt;(I2&amp;lt;U&amp;gt; i2, U u) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; i2.M(u);&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;The binding of the overload resolution in the thunk bodies happens before the substitution of the type parameters, so these always bind to the generic versions of the methods. As you would expect from the mappings above, this outputs&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;c3 explicit I1 103&lt;BR&gt;c3 class 104&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Again, this shows that source code order has an unfortunate semantic import.&lt;/P&gt;
&lt;P&gt;Given this unfortunate situation -- no spec guidance and an existing implementation that behaves strangely -- what would you do? (Of course "do nothing" is an option.) I'm interested to hear your ideas, and I'll describe what we actually did next time.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=569085" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Overload+Resolution/default.aspx">Overload Resolution</category></item><item><title>The Root of All Evil, Part Two</title><link>http://blogs.msdn.com/ericlippert/archive/2006/03/29/the-root-of-all-evil-part-two.aspx</link><pubDate>Thu, 30 Mar 2006 00:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:564324</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/564324.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=564324</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;There were a number of interesting comments to yesterday's posting about premature optimization. &lt;/P&gt;
&lt;P&gt;Several readers pointed out that there are various options we could take: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Do nothing. Maintain backwards compatibility and spec incompatibility. 
&lt;LI&gt;Change the spec to exactly match the current implementation. 
&lt;LI&gt;Change the spec and the implementation. 
&lt;LI&gt;Make the weird behaviour a warning now and an error later. 
&lt;LI&gt;Fix the implementation to match the specification, but add another compiler switch to go back to the previous behaviour. &lt;/LI&gt;&lt;/OL&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;These all have various pros and cons, and even for a relatively trivial spec incompatibility such as this one, we think very hard about what the right thing to do is. &lt;/P&gt;
&lt;P&gt;Option #2 sounded good, and I actually was an advocate of it for a few hours yesterday, right up until I dug into the optimization and discovered exactly what it was doing. If we were to change the specification to exactly match the behaviour, then the specification would read like this: &lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0000ff&gt;Implicit Enumeration Conversions &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0000ff&gt;There is an implicit conversion from any "magic zero" to any enumerated type. "Magic zero" is recursively defined as follows: &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0000ff&gt;&lt;/FONT&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;FONT color=#0000ff&gt;the integer literal zero, or &lt;/FONT&gt;
&lt;LI&gt;&lt;FONT color=#0000ff&gt;any magic zero + - | ^ any compile-time integer constant expression equal to zero, or &lt;/FONT&gt;
&lt;LI&gt;&lt;FONT color=#0000ff&gt;any compile-time integer expression * &amp;amp; any magic zero, or &lt;/FONT&gt;
&lt;LI&gt;&lt;FONT color=#0000ff&gt;any magic zero / % any non-zero compile-time constant integer expression, or &lt;/FONT&gt;
&lt;LI&gt;&lt;FONT color=#0000ff&gt;any magic zero * &amp;amp; any non-zero compile-time constant integer expression &lt;/FONT&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This means for example, that &lt;SPAN class=code&gt;(8*(0+(7-7)))&lt;/SPAN&gt; is a magic zero, but &lt;SPAN class=code&gt;(8*((7-7)+0)&lt;/SPAN&gt; is not. &lt;/P&gt;
&lt;P&gt;I think we can all agree that we don't want this nonsense in the specification. Changing the spec to exactly match the buggy behaviour leads to a crazy spec. &lt;/P&gt;
&lt;P&gt;We could change both the specification and the implementation. We could, for instance, say that any compile-time constant integer zero is implicitly convertible to any enumerated type. This means that nonsense like &lt;SPAN class=code&gt;(8*(0+(7-7)))&lt;/SPAN&gt; is assignable to enum, but at least it also means that &lt;SPAN class=code&gt;(8*((7-7)+0)&lt;/SPAN&gt; is too. &lt;/P&gt;
&lt;P&gt;Adding a new warning is a tempting idea, and we might end up doing it. Doing so means that it is easier to turn it into an error in a future release. New warnings, however, are expensive. They add new code paths to test, we have to test all the scenarios to make sure the warning always appears when it should, warnings have to be translated into a dozen languages, they have to be documented, the documentation has to be translated... it's not cheap. &lt;/P&gt;
&lt;P&gt;Adding a compiler switch is also a possibility, but also expensive. The more switches there are, again, more code paths, more tests, bigger testing matrix, the switch has to be documented, and so on. &lt;/P&gt;
&lt;P&gt;So now you see why premature optimization is the root of all evil. I've spent the better part of two days wrestling with this thing. Why? Because suppose one of these guys is in a lambda expression that needs to be translated into an expression tree. I want to make for darn sure that the translation is correct, and the more "optimizations" that happen before that transformation, the more the transformation is likely to be not as the user intended! But I can't remove the optimizations without breaking the type system! &lt;/P&gt;
&lt;P&gt;UPDATE: The thrilling conclusion is that we have made all constant-according-to-the-spec zero integers&amp;nbsp;convertible to any enum. This is a spec violation, but at least it is a consistent spec violation. In doing so I also introduced a bug, which I believe did ship to customers but which we have since fixed, whereby some "non-integer zeros" (like default instances of structs, or null references) were convertible to any enum. I apologize for the error. &lt;/P&gt;
&lt;P&gt;I also challenged you folks to come up with a situation where this premature optimization can screw up definite assignment checking. Reader Carlos found two. &lt;/P&gt;
&lt;P&gt;&lt;SPAN class=code&gt;int aa; int bb = 12; int cc; &lt;BR&gt;int dd = (aa * 0) + 12;&lt;BR&gt;if (bb * 0 == 0) cc = 123;&lt;BR&gt;Console.WriteLine(cc);&lt;BR&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;According to the spec, &lt;SPAN class=code&gt;aa&lt;/SPAN&gt; should be flagged as "used before definitely assigned" (even though really it doesn't matter), but because the premature optimization throws away the &lt;SPAN class=code&gt;aa&lt;/SPAN&gt;, the flow checker never sees it. Also according to the spec, &lt;SPAN class=code&gt;cc &lt;/SPAN&gt;should be flagged as "used before definitely assigned" (even though it always is assigned), but because the optimization throws away the &lt;SPAN class=code&gt;bb&lt;/SPAN&gt;, the flow checker does not realize that the conditional is not a compile-time-constant. &lt;/P&gt;
&lt;P&gt;The important thing here is not that the code gets it wrong. Indeed, one could make the argument that it gets it right. The problem is that it gets it right for the wrong reasons – it gets it right by accident, in violation of the specification. The definite assignment specification isn't supposed to be perfect, it's supposed to be practical and understandable and predictable and implementable. Undocumented extensions to it make it hard to know whether any two implementations of the spec will agree. &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=564324" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category></item></channel></rss>