<?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 : Language Design</title><link>http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx</link><description>Tags: Language Design</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Exact rules for variance validity</title><link>http://blogs.msdn.com/ericlippert/archive/2009/12/03/exact-rules-for-variance-validity.aspx</link><pubDate>Thu, 03 Dec 2009 14:32:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9923708</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>17</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9923708.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9923708</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;I thought it might be interesting for you all to get a precise description of how exactly it is that we determine when it is legal to put "in" and "out" on a type parameter declaration in C# 4. I'm doing this here because (1) it's of general interest, and (2) our attempt to make a more human-readable version of this algorithm in the draft C# 4.0 specification accidentally introduced some subtle errors. We're working on correcting those errors for the final release of the specification; until then, &lt;EM&gt;these definitions are the definitions I actually worked from to do the implementation&lt;/EM&gt;, so they're accurate. &lt;/P&gt;
&lt;P&gt;These definitions are pretty much stolen straight from the CLI spec section on variance; I am indebted to its authors for their careful and precise definitions.&lt;/P&gt;
&lt;P&gt;The first things we need to define are three kinds of "validity" for &lt;STRONG&gt;types&lt;/STRONG&gt;. I want to define "valid covariantly", "valid contravariantly" and "valid invariantly", but only as applied to &lt;STRONG&gt;types&lt;/STRONG&gt;. We'll talk about what makes an interface &lt;STRONG&gt;declaration&lt;/STRONG&gt; a valid one later; we need these definitions first.&lt;/P&gt;
&lt;P&gt;Before we get into a precise definition, I want to talk about what "valid covariantly" means logically. The idea that we are attempting to capture here boils down to "the type we're talking about is &lt;EM&gt;not contravariant&lt;/EM&gt;". Whether it is &lt;EM&gt;covariant&lt;/EM&gt;, we don't really care. All we care about it is that &lt;STRONG&gt;if it is valid covariantly, then it is not contravariant&lt;/STRONG&gt;. Similarly, by "valid contravariantly", we mean "not covariant".&lt;/P&gt;
&lt;P&gt;This leads us to our first brain-hurting definition: A type is "&lt;STRONG&gt;valid invariantly&lt;/STRONG&gt;"&amp;nbsp;if it is &lt;STRONG&gt;both&lt;/STRONG&gt; valid covariantly and valid contravariantly. That sounds a bit crazy -- how can it be valid invariantly if it is both covariant and contravariant? But "valid covariantly" does not mean "is covariant", it means "it's guaranteed to not be contravariant".&amp;nbsp;So if a type is valid covariantly and valid contravariantly, then it is guaranteed to be neither contravariant nor covariant, and therefore must be invariant.&lt;/P&gt;
&lt;P&gt;Anyway. We want to take any specific type and classify it as valid covariantly, valid contravariantly, or both, a.k.a., valid invariantly. (We don't need to worry about coming up with a term for the "or none of the above" case because in practice that case is never relevant.)&lt;/P&gt;
&lt;P&gt;A type is &lt;STRONG&gt;valid covariantly&lt;/STRONG&gt; if it is:&lt;/P&gt;
&lt;P&gt;1) a class, struct, nullable, enum, pointer, non-generic delegate or non-generic interface type.&lt;/P&gt;
&lt;P&gt;This should make sense. Remember, what we're getting at is "not contravariant". Classes and structs are either non-generic, in which case they are clearly not contravariant, or they are generic, in which case again they are not contravariant because we do not support variance on classes or structs.&amp;nbsp;Nullable types are just aliases for Nullable&amp;lt;T&amp;gt; which is a struct type, and therefore not variant. Enums&amp;nbsp;and pointers are non-generic so they are not variant. And non-generic delegates and interfaces are by definition not generic and therefore not variant either.&amp;nbsp;These&amp;nbsp;are the easy cases.&lt;/P&gt;
&lt;P&gt;2) An array type T[] where T is valid covariantly.&lt;/P&gt;
&lt;P&gt;Because we have array covariance in C#, but not array contravariance, we can make arrays valid covariantly. Again, remember, "valid covariantly" means "not contravariant".&lt;/P&gt;
&lt;P&gt;3) A generic type parameter type, if it was not declared as being contravariant.&lt;/P&gt;
&lt;P&gt;Generic type parameter types are of course types as far as the compiler is concerned. If you're inside the declaration of a generic interface then you can use its type parameters as types. In that context, such types are valid covariantly if they were not declared as contravariant (in).&lt;/P&gt;
&lt;P&gt;4) A constructed interface or delegate type X&amp;lt;T1, ... Tk&amp;gt; might be valid covariantly. To determine if it is, we examine each type argument differently, depending on whether the corresponding type parameter was declared as covariant (out), contravariant (in), or invariant (neither). If the ith&amp;nbsp;type parameter was declared as covariant, then Ti must be valid covariantly. If it was declared as contravariant, then Ti must be valid contravariantly. If it was declared as invariant, then Ti must be valid invariantly. &lt;/P&gt;
&lt;P&gt;As one would expect, covariant validity preserves the direction of validity; covariant parameters must be valid covariantly, contravariant parameters must be valid contravariantly.&lt;/P&gt;
&lt;P&gt;OK, I hope that was relatively painless. The rules for contravariant validity are similar; as one would expect from the "backwards" nature of contravariance, the directions are reversed in the complicated case:&lt;/P&gt;
&lt;P&gt;A type is &lt;STRONG&gt;valid contravariantly&lt;/STRONG&gt; if it is:&lt;/P&gt;
&lt;P&gt;1) a class, struct, nullable, enum, pointer, non-generic delegate or non-generic interface type.&lt;/P&gt;
&lt;P&gt;2) An array type T[] where T is valid contravariantly.&lt;/P&gt;
&lt;P&gt;Arrays are covariant in their element type. Covariance preserves the direction of variance. Therefore, to be valid contravariantly, an array (covariant in its element type) must be contravariantly valid in its element type.&lt;/P&gt;
&lt;P&gt;3) A generic type parameter type, if it was not declared as being covariant.&lt;/P&gt;
&lt;P&gt;Remember, "valid contravariantly" means "not covariant". It does not mean "contravariant".&lt;/P&gt;
&lt;P&gt;4) A constructed interface or delegate type X&amp;lt;T1, ... Tk&amp;gt; might be valid contravariantly. If the ith&amp;nbsp;type parameter was declared as contravariant, then Ti must be valid covariantly. If it was declared as covariant, then Ti must be valid contravariantly. If it was declared as invariant, then Ti must be valid invariantly. &lt;/P&gt;
&lt;P&gt;As one might expect, contravariant validity &lt;EM&gt;reverses&lt;/EM&gt; the direction of validity. &lt;/P&gt;
&lt;P&gt;Now perhaps you see why we wanted to rewrite these definitions into something more human-readable for the spec. And perhaps you also see why we accidentally introduced errors in doing so; bending your brain around all this logic is not always easy.&lt;/P&gt;
&lt;P&gt;OK, now that we've got that, we can make a definition of what it means for an interface to be valid. An interface must meet the following conditions:&lt;/P&gt;
&lt;P&gt;* The return types of&amp;nbsp;all non-void interface methods must be valid covariantly.&lt;/P&gt;
&lt;P&gt;* Every formal parameter type of&amp;nbsp;all interface methods must be valid contravariantly. (Invariantly if it is an out or ref parameter.)&lt;/P&gt;
&lt;P&gt;* For all generic methods on an interface,&amp;nbsp;every constraint on the generic method type parameters must be valid contravariantly.&lt;/P&gt;
&lt;P&gt;* All its base interface types&amp;nbsp;must be&amp;nbsp;valid covariantly.&lt;/P&gt;
&lt;P&gt;* The type of a property or indexer must be valid covariantly if it has a "getter" and valid contravariantly if it has a "setter".&lt;/P&gt;
&lt;P&gt;* Any formal parameter types of an indexer must be valid contravariantly.&lt;/P&gt;
&lt;P&gt;* The delegate types of all its events must be valid contravariantly.&lt;/P&gt;
&lt;P&gt;The first two are pretty straightforward; return types "go out" so they have to be valid covariantly, formal parameter types "go in", so they have to be valid contravariantly. But what's up with the third one? What do constraints on generic method type parameters have to do with interface validity?&lt;/P&gt;
&lt;P&gt;Well, let's suspend&amp;nbsp;the third rule&amp;nbsp;and see what goes wrong.&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;interface I&amp;lt;out T&amp;gt;&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void M&amp;lt;U&amp;gt;() where U : T; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // illegal; this has to be valid contravariantly but it is a covariant type parameter constraint.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Let it ride for now and demonstrate an error.&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;class C&amp;lt;T&amp;gt; : I&amp;lt;T&amp;gt; { public void M&amp;lt;U&amp;gt;() {} }&lt;BR&gt;// the constraint is inherited implicitly and not re-stated.&lt;/P&gt;
&lt;P&gt;I&amp;lt;Giraffe&amp;gt; igiraffe = new C&amp;lt;Giraffe&amp;gt;();&amp;nbsp;// C&amp;lt;T&amp;gt; implements I&amp;lt;T&amp;gt;&lt;BR&gt;I&amp;lt;Animal&amp;gt; ianimal = igiraffe; // interface is covariant in T&lt;BR&gt;ianimal.M&amp;lt;Turtle&amp;gt;(); // satisifies the constraint that U must be an Animal.&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Uh oh. ianimal is really an instance of&amp;nbsp;C&amp;lt;Giraffe&amp;gt;.&amp;nbsp;The M&amp;lt;U&amp;gt; method on C&amp;lt;Giraffe&amp;gt; inherits a requirement that U inherit from Giraffe. Turtle does not inherit from Giraffe. Therefore we've just violated the constraint on M&amp;lt;U&amp;gt;. The only places where we can catch this is in the declaration; every other step is&amp;nbsp;perfectly legal. Therefore, a constraint cannot be covariant. But if we make it contravariant (or invariant) then it all works out. For example, let's make a contravariant type parameter constraint:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;interface I2&amp;lt;in T&amp;gt; // contravariant this time&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void M&amp;lt;U&amp;gt;() where U : T; &lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;class C2&amp;lt;T&amp;gt; : I2&amp;lt;T&amp;gt; { public void M&amp;lt;U&amp;gt;() {} }&lt;BR&gt;I2&amp;lt;Animal&amp;gt; i2animal = new C2&amp;lt;Animal&amp;gt;();&amp;nbsp;// C2&amp;lt;T&amp;gt; implements I2&amp;lt;T&amp;gt;&lt;BR&gt;I2&amp;lt;Mammal&amp;gt; i2mammal = i2animal; // interface is contravariant in T&lt;BR&gt;i2mammal.M&amp;lt;Giraffe&amp;gt;(); // satisifies the constraint that U must be an Animal.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;And now everything is fine; the compile-time constraint checker verifies that Giraffe is Mammal; at runtime it must be Animal,&amp;nbsp;and so the compiler has verified that by verifying that&amp;nbsp;it is Mammal.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The rules for &lt;STRONG&gt;delegate declarations&lt;/STRONG&gt; are a straightforward simplification of the rules for interface declarations. To be a valid delegate declaration, the return type must be valid covariantly (or void), the formal parameter types must be valid contravariantly (or invariantly if they are out/ref), and any type parameter constraints must be valid contravariantly. &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9923708" 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/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><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx">Language Design</category></item><item><title>The Purpose, Revealed</title><link>http://blogs.msdn.com/ericlippert/archive/2009/11/25/the-purpose-revealed.aspx</link><pubDate>Wed, 25 Nov 2009 17:03:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9928668</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9928668.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9928668</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Interestingly enough, no one correctly guessed why I needed code in the compiler to transform a method argument list into a form that batched up the side effecting expressions, stuck their values in variables, and then called the method with the side-effect-free variable references. There certainly were some fascinating ideas in the comments though!&lt;/P&gt;
&lt;P&gt;The reason is quite mundane. We had a bug in the code that performs semantic analysis of calls with named arguments. One of our rules in C# that I've talked about a lot on this blog is that sub-expression evaluation occurs in left-to-right order. If you have a method &lt;SPAN class=code&gt;void&amp;nbsp;M(int&amp;nbsp;x,&amp;nbsp;int&amp;nbsp;y)&amp;nbsp;{} &lt;/SPAN&gt;and then a call site &lt;SPAN class=code&gt;M(y&amp;nbsp;:&amp;nbsp;F(),&amp;nbsp;x&amp;nbsp;:&amp;nbsp;G());&lt;/SPAN&gt; we cannot simply generate the code as though you'd written &lt;SPAN class=code&gt;M(G(),&amp;nbsp;F())&lt;/SPAN&gt;. The side effects of F have to happen before the side effects of G, so we generate code as though you'd said &lt;SPAN class=code&gt;temp1&amp;nbsp;=&amp;nbsp;F(); temp2&amp;nbsp;=&amp;nbsp;G(); M(y&amp;nbsp;:&amp;nbsp;temp1,&amp;nbsp;x&amp;nbsp;:&amp;nbsp;temp2);&lt;/SPAN&gt; and now we can generate the call as &lt;SPAN class=code&gt;M(temp2,&amp;nbsp;temp1);&lt;/SPAN&gt; without worrying about re-ordering a side effect. &lt;/P&gt;
&lt;P&gt;The bug was that the rewriter was not getting the reordering correct if the parameters were ref/out or the arguments were locals without side effects. As I often do when fixing a bug, I reasoned that the initial bug had been caused because the rewriter was under-specified. &lt;/P&gt;
&lt;P&gt;The fix will get into the initial release of C# 4, but the problems that Pavel identified with it -- that certain obscure side effects such as the order in which bad array accesses throw exceptions, or the order in which static class constructors execute, are not correctly preserved by my algorithm, will not be fixed for the initial release. Doing these correctly requires us to be able to generate temporaries of "reference to argument" types, which we've never done before and which our IL generator was not built to handle. Had we discovered the bug much earlier in the cycle, we probably could have applied a more solid fix, but it is too late now. &lt;/P&gt;
&lt;P&gt;Thanks again to Pavel for the great analysis, and thanks to our old friend nikov for reporting the bug in the first place. &lt;/P&gt;
&lt;P&gt;And happy thanksgiving to my readers in the United States! As I do every year, I'm roasting a turkey to feed fourteen people. I highly recommend the "brine the bird then&amp;nbsp;roast it upside-down" method described in The Joy Of Cooking. It's worked perfectly&amp;nbsp;for me for the last ten years straight.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9928668" 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/Code+Generation/default.aspx">Code Generation</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Software+development+methodology/default.aspx">Software development methodology</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/named+parameters/default.aspx">named parameters</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>123</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>Simple names are not so simple</title><link>http://blogs.msdn.com/ericlippert/archive/2009/11/02/simple-names-are-not-so-simple.aspx</link><pubDate>Mon, 02 Nov 2009 14:23:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9909292</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>14</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9909292.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9909292</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;C# has many rules that are designed to prevent some common sources of bugs and encourage good programming practices. So many, in fact, that it is often quite confusing to sort out exactly which rule has been violated. I thought I might spend some time talking about what the different rules are. We'll finish up with a puzzle.&lt;/P&gt;
&lt;P&gt;To begin with, it will be vital to understand &lt;A href="http://blogs.msdn.com/ericlippert/archive/2009/08/03/what-s-the-difference-part-two-scope-vs-declaration-space-vs-lifetime.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/08/03/what-s-the-difference-part-two-scope-vs-declaration-space-vs-lifetime.aspx"&gt;the difference between &lt;EM&gt;scope&lt;/EM&gt; and &lt;EM&gt;declaration space&lt;/EM&gt;&lt;/A&gt;. To refresh your memory of my earlier article: the &lt;EM&gt;scope&lt;/EM&gt; of an entity is &lt;EM&gt;the region of text in which that entity may be referred to by its unqualified name&lt;/EM&gt;. A &lt;EM&gt;declaration space&lt;/EM&gt; is a region of text in which &lt;EM&gt;no two things may have the same name &lt;/EM&gt;(with an exception for methods which differ by signature.) A "local variable declaration space" is a particular kind of declaration space used for declaring local variables; local variable declaration spaces have special rules for determining when they overlap.&lt;/P&gt;
&lt;P&gt;The next thing that you have to understand to make any sense o this is what a "simple name" is. A &lt;EM&gt;simple name&lt;/EM&gt; is always either just a plain identifier, like "x", or, in some cases, a plain identifier followed by a type argument list, like "Frob&amp;lt;int, string&amp;gt;". &lt;/P&gt;
&lt;P&gt;Lots of things are treated as "simple names" by the compiler: local variable declarations, lambda parameters, and so on, always have the first form of simple name in their declarations. When you say "Console.WriteLine(x);" the "Console" and "x" are simple names but the "WriteLine" is not. Confusingly, there are some textual entities which have the form of simple names, but are not treated as simple names by the compiler. We might talk about some of those situations in later fabulous adventures.&lt;/P&gt;
&lt;P&gt;So, without further ado, here are some relevant rules which are frequently confused. It's rules 3 and 4 that people find particularly confusing.&lt;/P&gt;
&lt;P&gt;1) It is illegal to refer to a local variable before its declaration. (This seems reasonable I hope.)&lt;BR&gt;2) It is illegal to have two local variables of the same name in the same local variable declaration space or nested local variable declaration spaces.&lt;BR&gt;3) Local variables are in scope throughout the entire block in which the declaration occurs. This is in contrast with C++, in which local variables are in scope in their block only at points after the declaration.&lt;BR&gt;4) For every occurrence of a simple name, whether in a declaration or as part of an expression, all uses of that simple name within the immediately enclosing local variable declaration space must refer to the same entity.&lt;/P&gt;
&lt;P&gt;The purpose of all of these rules is to prevent the class of bugs in which the reader/maintainer of the code is tricked into believing they are referring to one entity with a simple name, but are in fact accidentally referring to another entity entirely. These rules are in particular designed to prevent nasty surprises when performing what ought to be safe refactorings. &lt;/P&gt;
&lt;P&gt;Consider a world in which we did not have rules 3 and 4. In that world, this code would be legal:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;class C&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; int x;&lt;BR&gt;&amp;nbsp; void M()&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 100 lines of code&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; x = 20; // means "this.x";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(x); // means "this.x"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 100 lines of code&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int x = 10;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(x); // means "local x"&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This is hard on the person reading the code, who has a reasonable expectation that the two "Console.WriteLine(x)" lines do in fact both print out the contents of the same variable. But it is particularly nasty for the maintenance programmer who wishes to impose a reasonable coding standard upon this body of code. "Local variables are declared at the top of the block where they're used" is a reasonable coding standard in a lot of shops. But changing the code to:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;class C&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; int x;&lt;BR&gt;&amp;nbsp; void M()&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int x;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 100 lines of code&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; x = 20; // no longer means "this.x";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(x); // no longer means "this.x"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 100 lines of code&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; x = 10;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(x); // means "local x"&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;} &lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;changes the meaning of the code! We wish to discourage authoring of multi-hundred-line methods, but making it harder and more error-prone to refactor them into something cleaner is not a good way to achieve that goal.&lt;/P&gt;
&lt;P&gt;Notice that the original version of this program, rule 3 means that the program violates rule 1 -- the first usage of "x" is treated as a reference to the local before it is declared. The fact that it violates rule 1 because of rule 3 is precisely what prevents it from being a violation of rule 4! The meaning of "x" is consistent throughout the block; it always means the local, and therefore is sometimes used before it is declared. If we scrapped rule 3 then this would be a violation of rule 4, because we would then have two inconsistent meanings for the simple name "x" within one block.&lt;/P&gt;
&lt;P&gt;Now, these rules do not mean that you can refactor willy-nilly. We can still construct situations in which similar refactorings fail. For example:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;class C&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; int x;&lt;BR&gt;&amp;nbsp; void M()&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 100 lines of code&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x = 20; // means "this.x";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(x); // means "this.x"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 100 lines of code&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int x = 10;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(x); // means "local x"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This is perfectly legal. We have the same simple name being used two different ways in two different blocks, but the immediately enclosing block of each usage does not overlap that of any other usage. The local variable is in scope throughout its immediately enclosing block, but that block does not overlap the block above. In this case, it is safe to refactor the declaration of the local to the top of its block, but not safe to refactor the declaration to the top of the outermost block; that would change the meaning of "x" in the first block. Moving a declaration up is almost always a safe thing to do; moving it out is not necessarily safe. &lt;/P&gt;
&lt;P&gt;Now that you know all that, here's a puzzle for you, a puzzle that I got completely wrong the first time I saw it:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;using System.Linq;&lt;BR&gt;class Program&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; static void Main()&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int[] data = { 1, 2, 3, 1, 2, 1 };&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (var m in from m in data orderby m select m)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Console.Write(m);&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;It certainly looks like name "m" is being used multiple times to mean different things. Is this program legal? If yes, why do the rules for not re-using simple names&amp;nbsp;not apply? If no, precisely what rule has been violated?&amp;nbsp; &lt;/P&gt;
&lt;P&gt;[Eric is on vacation; this posting was pre-recorded.]&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9909292" 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/Puzzles/default.aspx">Puzzles</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/declaration+spaces/default.aspx">declaration spaces</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/scope/default.aspx">scope</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Simple+Names/default.aspx">Simple Names</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/local+variables/default.aspx">local variables</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/refactoring/default.aspx">refactoring</category></item><item><title>As Timeless As Infinity</title><link>http://blogs.msdn.com/ericlippert/archive/2009/10/15/as-timeless-as-infinity.aspx</link><pubDate>Thu, 15 Oct 2009 13:25:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9904452</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>32</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9904452.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9904452</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;&lt;STRONG&gt;User:&lt;/STRONG&gt; Recently I found out about a peculiar behaviour concerning division by zero in floating point numbers in C#. It does not throw an exception, as with integer division,&amp;nbsp;but rather returns an "infinity". Why is that?&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eric:&lt;/STRONG&gt; As I've often said, "why" questions are difficult for me&amp;nbsp;to answer. My first attempt at an answer to a "why" question is usually "because that's what the specification says to do"; this time is no different. The C# specification says to do that in section 4.1.6. But we're only doing that because that's what&amp;nbsp;the IEEE standard for floating point arithmetic says to do. We wish to be compliant with the established industry standard. See &lt;A href="http://en.wikipedia.org/wiki/IEEE_754-1985" mce_href="http://en.wikipedia.org/wiki/IEEE_754-1985"&gt;IEEE standard 754-1985&lt;/A&gt; for details. Most floating point&amp;nbsp;arithmetic&amp;nbsp;is done in hardware these days, and most hardware is compliant with this specification.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;User:&lt;/STRONG&gt;&amp;nbsp;It seems to me that division by zero is a bug no matter how you look at it!&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eric:&lt;/STRONG&gt; Well, since clearly that is not how the members of the IEEE standardization committee looked at it in 1985, your statement that it must be a bug "no matter how you look at it" must be incorrect. Some industry experts do not look at it that way.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;User:&lt;/STRONG&gt;&amp;nbsp;Good point. What motivated this design decision?&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eric:&lt;/STRONG&gt; I wasn't there; I was busy playing&amp;nbsp;Jumpman on my Commodore 64 at the time. But my educated guess is that &lt;STRONG&gt;it is desirable for all possible operations on all floats to produce a well-defined float result&lt;/STRONG&gt;. Mathematicians would call this a "closure" property; that is, the set of floating point numbers is "closed" over all operations.&lt;/P&gt;
&lt;P&gt;Positive infinity seems like a reasonable choice for dividing a positive number by zero. It seems plausible because of course the limit of 1 / x as x goes to zero (from above)&amp;nbsp;is "positive infinity", so why shouldn't 1/0 be the number "positive infinity"?&lt;/P&gt;
&lt;P&gt;Now, speaking &lt;EM&gt;as a mathematician&lt;/EM&gt;, I find that argument specious. A thing&amp;nbsp;and its limit need not have any particular property in common; it is fallacious to reason that just because, say, a sequence has a particular limit that a fact about the limit is also a fact about the sequence. Mathematically, "positive infinity" (in the sense of a limit of a real-valued function; let's leave transfinite ordinals, hyperbolic geometry, and all of that&amp;nbsp;other stuff out of this discussion)&amp;nbsp;is not a number at all and should not be treated as one; rather, it's a terse way of saying "the limit does not exist because the sequence diverges upwards". &lt;/P&gt;
&lt;P&gt;When we divide by zero, essentially what we are saying is "solve the equation x * 0 = 1"; the solution to that equation is not "positive infinity", it is "I cannot because there is no solution to that equation". It's just the same as asking to solve the equation "x + 1 = x" -- saying "x is positive infinity" is not a solution; there is no solution.&lt;/P&gt;
&lt;P&gt;But speaking &lt;EM&gt;as a practical engineer&lt;/EM&gt; who uses floating point numbers to do an imprecise approximation of ideal arithmetic, this seems like a perfectly reasonable choice. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;User:&lt;/STRONG&gt;&amp;nbsp;But surely it is impossible for the hardware to represent "infinity".&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eric:&lt;/STRONG&gt; It certainly is possible. You've got 32 bits in a single-precision float; that's over four billion possible floats. All bit patterns of the form &lt;/P&gt;
&lt;P&gt;?11111111??????????????????????? &lt;/P&gt;
&lt;P&gt;are reserved for "not-a-number" values. That's over sixteen million possible NaN combinations. Two of those sixteen million NaN bit patterns are reserved to mean positive and negative infinity. Positive infinity is the bit pattern 01111111100000000000000000000000 and negative infinity is 11111111100000000000000000000000. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;User:&lt;/STRONG&gt;&amp;nbsp;Do all languages and applications use this convention of division-by-zero-becomes-infinity?&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eric: &lt;/STRONG&gt;No.&amp;nbsp;For example, C#&amp;nbsp;and JScript do but&amp;nbsp;VBScript does not. VBScript gives an error if you do that.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;User:&lt;/STRONG&gt;&amp;nbsp;Then how do language implementors get the desired behaviour for each language if these semantics are implemented by the hardware?&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eric: &lt;/STRONG&gt;There are two basic techniques. First, many chips which implement this standard allow&amp;nbsp;the programmer&amp;nbsp;to make float division by zero an exception rather than an infinity. On the 80x87 chip, for example, you can use bit two of the precision control register to determine whether division by zero returns an infinity or&amp;nbsp;throws a hardware exception. &lt;/P&gt;
&lt;P&gt;Second, if you don't want it to be a hardware exception but do want it to be a software exception, then you can check bit two of the status register after each division;&amp;nbsp;it records whether there was&amp;nbsp;a recent divide-by-zero event. &lt;/P&gt;
&lt;P&gt;The latter strategy is used by VBScript; after we perform a division operation we check to see whether the status register recorded a divide-by-zero operation; if it did, then the VBScript runtime creates a divide-by-zero error and the usual VBScript error management&amp;nbsp;process takes over, same as any other error.&lt;/P&gt;
&lt;P&gt;Similar bits exist for other operations that seem like they might be better treated as exceptions, like numeric overflow.&lt;/P&gt;
&lt;P&gt;The existence of the "hardware exception" bits creates problems for the modern&amp;nbsp;language implementor, because we are now often in a world where code written in multiple languages from multiple vendors is running in the same process. Control bits on hardware are the ultimate "global state", and we all know how irksome it is to have global, public state that random code can stomp on. &lt;/P&gt;
&lt;P&gt;For example: I might be misremembering some details, but I seem to recall that Delphi-authored controls set the "overflows cause exceptions" bit. That is, the Delphi implementors did not use the VBScript strategy of "try it, allow it to succeed, and check to see whether the&amp;nbsp;overflow bit was set in the status register". Rather, they used the "make the hardware throw an exception and then catch the exception" strategy. This is deeply unfortunate.&amp;nbsp;When a VBScript script&amp;nbsp;calls a Delphi-authored control, the control flips the bit to force exceptions but it never "unflips" it. If, later on in the script, the VBScript program does an overflow, then we get an unhandled hardware exception because the bit is still set, even though the Delphi control might be long gone! I fixed that by saving away the state of the control register before calling into a component and restoring it when control returns. That's not ideal, but there's not much else we can do.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;User:&lt;/STRONG&gt;&amp;nbsp;Very enlightening! I will be sure to pass this information along to my coworkers. I would be delighted to see a blog post on this.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eric: &lt;/STRONG&gt;And here you go!&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=9904452" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/VBScript/default.aspx">VBScript</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/Floating+Point+Arithmetic/default.aspx">Floating Point Arithmetic</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Dialogue/default.aspx">Dialogue</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/exception+handling/default.aspx">exception handling</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Delphi/default.aspx">Delphi</category></item><item><title>Why No Extension Properties?</title><link>http://blogs.msdn.com/ericlippert/archive/2009/10/05/why-no-extension-properties.aspx</link><pubDate>Mon, 05 Oct 2009 16:29:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9899167</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>24</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9899167.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9899167</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;I'm frequently asked "you guys added extension methods to C# 3, so why not add extension properties as well?"&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Good question.&lt;/P&gt;
&lt;P&gt;First, let me talk a bit about C# 3. Clearly the big feature in C# 3 was LINQ. In a sense we had only three features in C# 3:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;everything necessary for LINQ -- implicitly typed locals, anonymous types, lambda expressions, extension methods, object and collection initializers, query comprehensions, expression trees, improved method type inference&lt;/LI&gt;
&lt;LI&gt;partial methods&lt;/LI&gt;
&lt;LI&gt;automatically implemented&amp;nbsp;properties&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The latter two were&amp;nbsp;tiny compared to the&amp;nbsp;items in that&amp;nbsp;first bucket. On the design side, the syntax and semantics of both features are straightforward. On the implementation side, we already had the mechanisms in place to remove a call site; partial methods and conditional methods are pretty much the same thing behind the scenes. Auto props were also straightforward to analyze and generate code for. The testing burden was not particularly&amp;nbsp;large for these features either.&lt;/P&gt;
&lt;P&gt;The C# team was "the long pole" for the 2008 release of Visual Studio and the .NET Framework. By that I mean that if you took the amount of time required to do the work&amp;nbsp;each team signed up for, given our level of staffing, blah blah blah, and made a pole proportionally long for each team in Developer Division, the C# pole would have been the longest pole. Which means that every other team in devdiv had slack in their schedule, but&amp;nbsp;if we slipped our schedule a day,&amp;nbsp;the new VS/CLR&amp;nbsp;would also ship a day late. If any other team slipped a day, well, as long as that didn't make their pole longer than ours, they were still OK. Within the team, dividing up the work amongs the various development team members, the "long pole" work was the lambda binding and method type inference work, which was mine. So in a sense, every day that I was late, we'd slip the whole product that many days. (No pressure!)&lt;/P&gt;
&lt;P&gt;Fortunately we have an excellent team here, we all supported each other very well through that release, picked up each other's slack when necessary, and delivered a quality release in plenty of time. My point is&amp;nbsp;simply that &lt;STRONG&gt;unless a feature was either necessary for LINQ, or small and orthogonal and easy to cut if necessary (like the other two), it got cut immediately&lt;/STRONG&gt;. There was no way we were going to risk slipping the entire product for any feature that was both &lt;EM&gt;complex&lt;/EM&gt; and &lt;EM&gt;unnecessary&lt;/EM&gt;.&lt;/P&gt;
&lt;P&gt;It was of course immediately obvious that the natural companion to extension methods is extension properties. It's less obvious, for some reason, that extension events, extension operators, extension constructors (also known as "the factory pattern"), and so on, are also natural companions. But we didn't even &lt;EM&gt;consider&lt;/EM&gt; designing extension properties for C# 3; we knew that they were not necessary and would add risk to an already-risky schedule for no compelling gain. &lt;/P&gt;
&lt;P&gt;So now we come to C# 4. &lt;/P&gt;
&lt;P&gt;As I'm fond of pointing out, the answer to every question of the form "why doesn't product X have&amp;nbsp;feature Y?" is the same.&amp;nbsp;It's because in order for a product to have a feature, that feature must be:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;thought of in the first place&lt;/LI&gt;
&lt;LI&gt;desired&lt;/LI&gt;
&lt;LI&gt;designed&amp;nbsp;&lt;/LI&gt;
&lt;LI&gt;specified&lt;/LI&gt;
&lt;LI&gt;implemented&lt;/LI&gt;
&lt;LI&gt;tested&lt;/LI&gt;
&lt;LI&gt;documented&lt;/LI&gt;
&lt;LI&gt;shipped to customers&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;You've got to hit every single one of those things,&amp;nbsp;otherwise, no feature.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;When we started working on C# 4, we made a list of every feature request we'd heard of. It had hundreds of features on it. &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2008/10/08/the-future-of-c-part-one.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2008/10/08/the-future-of-c-part-one.aspx"&gt;As I described last year&lt;/A&gt;, we categorized that list into "gotta have / nice to have / bad idea" buckets. Extension properties were in the "gotta have" bucket. We then looked at our available budget -- which was not so much measured in dollars as in available designers, developers, testers, writers and management multiplied by available time -- and determined that we did not have the resources to do more than about half the things in the "gotta have" bucket. So we cut half that stuff. Extension properties made it past that cut.&lt;/P&gt;
&lt;P&gt;We then designed the feature. We had many hours of debate about the proposed syntax on the declaration side, how to call an extension property getter or setter "directly" as a static method, and so on. We came up with a syntax we could agree was acceptable, designed the semantics, wrote up a draft specification, and started writing code and test plans.&lt;/P&gt;
&lt;P&gt;By the time the code was in reasonable shape -- not yet seriously tested, but usable and compliant with the spec -- we'd been having meetings with the WPF team. WPF developers&amp;nbsp;were the assumptive primary consumers of extension properties. WPF&amp;nbsp;already has a mechanism that resembles extension properties; it would be nice to unify that mechanism with our mechanism. Unfortunately, after taking a deep look at their real-world scenarios, we came to the disappointing conclusion that we had designed the wrong thing; this was not actually a feature that would solve their problems.&lt;/P&gt;
&lt;P&gt;This is, admittedly, in a sense a failure of the design process. In retrospect, we should have gotten input and feedback from the primary customer much earlier. Had we done that then they could have either influenced the design to make something that would work for them, or we could have cut the feature without taking on the expense of writing spec, code and test plans. &lt;/P&gt;
&lt;P&gt;But when you're in an unfortunate situation, you've got to decide to stop throwing good money after bad. Rather than take on the additional costs -- testing, documentation, shipping, and then maintenance of the feature for the rest of the life of the language -- in exchange for a feature that did not serve the needs of our customers, we cut the feature. At that point we did not feel confident that we had enough cycles remaining to redesign the feature the right way.&lt;/P&gt;
&lt;P&gt;Therefore, sadly, no extension properties in C# 4. Perhaps in a hypothetical future version of C#.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9899167" 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/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/extension+properties/default.aspx">extension properties</category></item><item><title>What's the difference between a partial method and a partial class?</title><link>http://blogs.msdn.com/ericlippert/archive/2009/09/14/what-s-the-difference-between-a-partial-method-and-a-partial-class.aspx</link><pubDate>Mon, 14 Sep 2009 18:16:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9895009</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>32</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9895009.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9895009</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Like "fixed" and "into", "partial" is also used in two confusingly similar-yet-different ways in C#. &lt;/P&gt;
&lt;P&gt;The purpose of a partial class is to allow you to textually break up a class declaration into multiple parts, usually parts found in separate files. The motivation for this feature was machine-generated code that is to be extended by the user by adding to it directly. When you draw a form in the forms designer, the designer generates a class for you representing that form. You can then further customize that class by adding more code to it. If you can edit the machine-generated code then any number of problems arise. What if it is re-generated? What if the machine is using the code itself as a persisted state for design-time information about the class, and your edit messes up the machine's parser? It's much better to simply put the machine-generated half in its own file, generate a comment that says "can't touch this", and put the user code in its own location.&lt;/P&gt;
&lt;P&gt;There are other uses of partial classes that do not involve machine-generated code but they are relatively rare. Some cases where I see partial classes used are:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;If a class is really large and implements a bunch of interfaces, sometimes one interface implementation per file makes sense. More often though this is a bad code smell which indicates a class that is trying to do too much; it might be better to split this thing up into multiple classes.&lt;/LI&gt;
&lt;LI&gt;It's somtimes nice to&amp;nbsp;put nested classes in their own files; making the containing class partial is the only good way to do that.&lt;/LI&gt;
&lt;LI&gt;And so on.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Partial methods are a subtly different story. Like partial classes, partial methods are about combining multiple declarations of the same method to make machine-generated code scenarios better. But though the high-level purpose of the feature is the same, the details are rather different.&lt;/P&gt;
&lt;P&gt;The way a partial method works is there are two declarations, the "latent" declaration and the "actual" declaration. The latent declaration does not have a body, like it was an abstract method. The actual declaration does. The latent declaration goes in the machine-generated side of&amp;nbsp;a partial class, the actual declaration goes in the human-authored side. If there is an actual declaration, then the latent declaration is completely ignored. But if there is no actual declaration then all calls to the&amp;nbsp;method are removed, just&amp;nbsp;as it the method were&amp;nbsp;compiled with the conditional attribute! And in fact, the latent declaration is also logically removed when we spit out the metadata for the generated class; it's as if it never was.&lt;/P&gt;
&lt;P&gt;The reason for this behaviour is because we wanted to enable this scenario:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;&amp;nbsp;// Machine generated code:&lt;BR&gt;partial class MyFoo&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; void ButtonClickEventHandler(/*whatever*/)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // call user code to see if they want to do anything at this time&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; OnBeforeButtonClick(whatever);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;blah blah blah&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // call user code again&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; OnAfterButtonClick(whatever);&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; partial void OnBeforeButtonClick(/*whatever*/);&amp;nbsp;&lt;BR&gt;&amp;nbsp; partial void OnAfterButtonClick(/*whatever*/); &lt;BR&gt;...&lt;BR&gt;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;The user is going to be customizing the partial class; by putting in partial methods, the machine-generated side can create simple customization points all over the show that the user can then implement. But consider the down sides of this in a world without partial methods. The user is forced to implement empty methods. If they do not, they get errors. There are potentially hundreds of these empty methods to implement, which is vexing. And each of those methods generates a non-trivial amount of metadata, making the final binary larger than it needs to be. Disk space is cheap but network latency has replaced disk space as the factor that discourages large assemblies. If we can eliminate that metadata burden, that would be great.&lt;/P&gt;
&lt;P&gt;Partial methods fit the bill. The user can provide actual implementations for as many methods as they choose, and now this becomes a "pay to play" model; you get as much&amp;nbsp;implementation&amp;nbsp;expense as the number of actual methods you implement.&lt;/P&gt;
&lt;P&gt;The name of the feature during the design process was "latent and actual methods"; we strongly considered adding new keywords "latent" and "actual". But since the feature only makes sense in partial class scenarios, we decided to re-use the existing contextual keyword "partial" and renamed the feature. Hopefully the consonance between the two uses of "partial" helps more than the subtle differences hurt.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;SUPER EXTRA BONUS: Yet more partiality&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;We considered adding&amp;nbsp;a third&amp;nbsp;kind of "partiality" to C# 4; this feature made it through the design phase but got cut before implementation. (If there is high demand, we'll consider adding it to hypothetical future versions of C#.)&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Sometimes you're in a machine-generated code scenario like this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;// Machine generated&lt;BR&gt;partial class C&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; int blah;&lt;BR&gt;...&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;and then in the user-generated side of things, you want to do something like:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;// User generated&lt;BR&gt;partial class C : ISerializable&lt;BR&gt;{&lt;BR&gt;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;And oh heck, I need to&amp;nbsp;put the NotSerialized attribute on blah, but I cannot edit the text of blah because when it gets re-generated, that will be lost. &lt;/P&gt;
&lt;P&gt;The idea of this new kind of partiality is to re-state the declaration of a member -- a field, method, nested type, whatever -- with metadata attributes. It's like a latent/actual method but in reverse; the "actual" thing is in the machine-generated side, the "latent" thing in the user-generated side is just there to add metadata:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;[NotSerialized] &lt;STRONG&gt;partial&lt;/STRONG&gt; int blah; // not actually a&amp;nbsp;declaration of a field&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;I like this feature but during the design process I pushed back hard on using the "partial" keyword to have a third meaning subtly different from the other two. Adding this confusion once seemed justifiable, but twice? That's pushing it. We therefore settled on adding another contextual keyword:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;[NotSerialized]&amp;nbsp;&lt;STRONG&gt;existing&lt;/STRONG&gt; int blah; // not actually a&amp;nbsp;declaration of a field&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Decorating a declaration with "existing" would mean "this is not a real declaration, this is a mention of an existing declaration; please verify that such a declaration exists somewhere else in this partial class, and add this metadata to that member".&lt;/P&gt;
&lt;P&gt;Like I said, this handy feature got cut because of resource constraints. If you have really awesome scenarios that this would make easier, I'd love to hear about them; obviously I cannot make any promises about possible future features of unannounced, entirely hypothetical products. But real user scenarios are a highly motivating factor in getting budget for features.&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=9895009" 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/Language+Design/default.aspx">Language Design</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/What_2700_s+The+Difference_3F00_/default.aspx">What's The Difference?</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/keywords/default.aspx">keywords</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/existing/default.aspx">existing</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/partial/default.aspx">partial</category></item><item><title>What's the Difference? Part Three: fixed vs. fixed</title><link>http://blogs.msdn.com/ericlippert/archive/2009/08/27/what-s-the-difference-between-fixed-and-fixed.aspx</link><pubDate>Thu, 27 Aug 2009 16:43:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9877647</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>16</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9877647.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9877647</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;I got an email the other day that began:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;I have a question about fixed sized buffers in C#:&lt;/EM&gt;&amp;nbsp;&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;unsafe struct FixedBuffer {&amp;nbsp;public fixed int buffer[100]; }&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;&lt;EM&gt;Now by declaring buffer as fixed it is not movable...&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;And my heart sank. This is one of those deeply unfortunate times when subtle choices made in the details of language design encourage misunderstandings.&lt;/P&gt;
&lt;P&gt;When doing pointer arithmetic in unsafe code on a managed object, you need to make sure that the garbage collector does not move the memory you're looking at. If a collection on another thread happens while you're doing pointer arithmetic on an object, the pointer can get all messed up. Therefore, C# classifies all variables as "fixed" or "movable". If you want to do pointer arithmetic on a movable object, you can use the "fixed" keyword to say "this local variable contains data which the garbage collector should not move."&amp;nbsp;When a collection happens, the garbage collector needs to look at all the local variables for&amp;nbsp;in-flight calls&amp;nbsp;(because of course, stuff that is in local variables needs to stay alive); if it sees a "fixed" local variable then it makes a note to itself to not move that memory, even if that fragments the managed heap. (This is why it is important to keep stuff fixed for as little time as possible.) So typically, we use "fixed' to mean "fixed in place". &lt;/P&gt;
&lt;P&gt;But that's not what "fixed" means in this context; this means "the buffer in question is fixed in size to be one hundred ints" -- basically, it's the same as generating one hundred int fields in this structure.&lt;/P&gt;
&lt;P&gt;Obviously we often use the same keyword to mean conceptually the same thing. For example, we use the keyword "internal" in many ways in C#, but all of them are conceptually the same. It is only ever used to mean "accessibility to some entity is unrestricted to all code in this assembly".&lt;/P&gt;
&lt;P&gt;Sometimes we use the same keyword to mean two completely different things, and rely upon context for the user to figure out which meaning is intended. For example:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;var results = from c in customers &lt;STRONG&gt;where&lt;/STRONG&gt; c.City == "London" select c;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;vs&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;class C&amp;lt;T&amp;gt; &lt;STRONG&gt;where&lt;/STRONG&gt; T : IComparable&amp;lt;T&amp;gt;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;It should be clear that "where" is being used in two completely different ways: to build a filter clause in a query, and to declare a type constraint on a generic type parameter.&lt;/P&gt;
&lt;P&gt;We cause people to run into trouble when one keyword is used in two different ways but the difference is &lt;EM&gt;subtle&lt;/EM&gt;, like our example above. The user's email went on to ask a whole bunch of questions which were predicated on the incorrect assumption that a fixed-in-size buffer is automatically fixed in place in&amp;nbsp;memory. &lt;/P&gt;
&lt;P&gt;Now, one could say that this is just an unfortunate confluence of terms; that "fixed in size" and "fixed in place" just happen to both use the word "fixed" in two different ways, how vexing. But the connection is deeper than that: &lt;STRONG&gt;you cannot safely access the data stored in a &lt;EM&gt;fixed-in-size&lt;/EM&gt; buffer unless the container of the buffer has been &lt;EM&gt;fixed in place&lt;/EM&gt;.&lt;/STRONG&gt; The two concepts are actually quite &lt;EM&gt;strongly related&lt;/EM&gt; in this case, but not at all &lt;EM&gt;the same&lt;/EM&gt;. &lt;/P&gt;
&lt;P&gt;On the one hand it might have been less confusing to use &lt;EM&gt;two&lt;/EM&gt; keywords, say "pinned" and "fixed". But on the other hand, both usages of "fixed" are only valid in unsafe code. A key assumption of all unsafe code features is that if you are willing to use unsafe code in C#, then you are already an expert programmer who fully understands memory management in the CLR. That's why we make you write "unsafe" on the code; it indicates that you're turning off the safety system and you know what you're doing.&lt;/P&gt;
&lt;P&gt;A considerable fraction of the keywords of C# are used in two or more ways: fixed, into, partial, out, in, new, delegate, where, using, class, struct, true, false, base, this, event, return and void all have at least two different meanings. Most of those are clear from the context, but at least the first three -- fixed, into and partial -- have caused enough confusion that I've gotten questions about the differences from perplexed users. I'll take a look at "into" and "partial" next.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9877647" 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/Language+Design/default.aspx">Language Design</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/unsafe+code/default.aspx">unsafe code</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/keywords/default.aspx">keywords</category></item><item><title>Iterator Blocks Part Seven: Why no anonymous iterators?</title><link>http://blogs.msdn.com/ericlippert/archive/2009/08/24/iterator-blocks-part-seven-why-no-anonymous-iterators.aspx</link><pubDate>Mon, 24 Aug 2009 16:23:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9872415</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>21</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9872415.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9872415</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;This annotation to a comment in part five I think deserves to be promoted to a post of its own. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Why do we disallow anonymous iterators?&lt;/STRONG&gt; I would love to have anonymous iterator blocks.&amp;nbsp; I want to say something like:&lt;/P&gt;
&lt;P&gt;&lt;SPAN class=code&gt;IEnumerable&amp;lt;int&amp;gt; twoints = ()=&amp;gt;{ yield return x; yield return x*10; }; &lt;BR&gt;foreach(int i in twoints) ... &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;It would be totally awesome to be able to build yourself a little sequence generator in-place that closed over local variables. The reason why not is straightforward: the benefits don't outweigh the costs. The awesomeness of making sequence generators in-place is actually pretty small in the grand scheme of things and nominal methods do the job well enough in most scenarios. So the benefits are not that compelling. &lt;/P&gt;
&lt;P&gt;The costs are large. Iterator rewriting is the most complicated transformation in the compiler, and anonymous method rewriting is the second most complicated. Anonymous methods can be inside other anonymous methods, and anonymous methods can be inside iterator blocks. Therefore, what we do is first we rewrite all anonymous methods so that they become methods of a closure class. This is the second-last thing the compiler does before emitting IL for a method. Once that step is done, the iterator rewriter can assume that there are no anonymous methods in the iterator block; they've all be rewritten already. Therefore the iterator rewriter can just concentrate on rewriting the iterator, without worrying that there might be an unrealized anonymous method in there. &lt;/P&gt;
&lt;P&gt;Also, iterator blocks never "nest", unlike anonymous methods. The iterator rewriter can assume that all iterator blocks are "top level".&lt;/P&gt;
&lt;P&gt;If anonymous methods are allowed to contain iterator blocks, then both those assumptions go out the window. You can have an iterator block that contains an anonymous method that contains an anonymous method that contains an iterator block that contains an anonymous method, and... yuck. Now we have to write a rewriting pass that can handle nested iterator blocks and nested anonymous methods at the same time, merging our two most complicated algorithms into one far more complicated algorithm. It would be really hard to design, implement, and test. We are smart enough to do so, I'm sure. We've got a smart team here. But we don't want to take on that large burden for a "nice to have but not necessary" feature.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9872415" 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/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/Iterators/default.aspx">Iterators</category></item><item><title>Arrays of arrays</title><link>http://blogs.msdn.com/ericlippert/archive/2009/08/17/arrays-of-arrays.aspx</link><pubDate>Mon, 17 Aug 2009 17:25:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9846730</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>47</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9846730.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9846730</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Most people understand that there’s a difference between a “rectangular” and a “ragged” two-dimensional array.&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;int[,] rectangle = { &lt;BR&gt;&amp;nbsp; {10, 20}, &lt;BR&gt;&amp;nbsp; {30, 40}, &lt;BR&gt;&amp;nbsp; {50, 60} };&lt;BR&gt;int[][] ragged = { &lt;BR&gt;&amp;nbsp; new[] {10}, &lt;BR&gt;&amp;nbsp; new[] {20, 30}, &lt;BR&gt;&amp;nbsp; new[] {40, 50, 60} };&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Here we have a two-dimensional array with six elements, arranged in three rows of two elements each. And we have a one-dimensional array with three elements, where each element is itself a one-dimensional array with one, two or three elements.&lt;/P&gt;
&lt;P&gt;That’s all very straightforward. Where things get brain-destroying is when you try to make a ragged array of two-dimensional arrays.&amp;nbsp; Quick, don’t think, just answer. &lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;int[,][] crazy;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;What is the type of crazy?&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Option one:&lt;/STRONG&gt; It’s a one-dimensional array, each element is a two-dimensional array of ints.&lt;BR&gt;&lt;STRONG&gt;Option two:&lt;/STRONG&gt; It’s a two-dimensional array, each element is a one-dimensional array of ints.&lt;/P&gt;
&lt;P&gt;OK, now that you have your snap answer, think about it carefully. Does your answer change?&lt;/P&gt;
&lt;P&gt;I’m not going to tell you the answer just yet. Instead let’s explore the consequences of each possibility.&lt;/P&gt;
&lt;P&gt;&lt;U&gt;Consequence One&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;Surely the way you make any type into an array is to append &lt;SPAN class=code&gt;[]&lt;/SPAN&gt; to the type specification, right? But in option two, you stick the &lt;SPAN class=code&gt;[,]&lt;/SPAN&gt; into the &lt;EM&gt;middle&lt;/EM&gt;. &lt;/P&gt;
&lt;P&gt;Option two is weird. Option one is sensible.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;But wait.&amp;nbsp;If [,][] means "a 1-d of 2-d's", then &lt;EM&gt;the order you read it off the page&amp;nbsp;opposes the order you say it&lt;/EM&gt; -- it looks like two-d-thing-followed-by-one-d-thing, so why &lt;EM&gt;shouldn't&lt;/EM&gt; it read "a 2-d of 1-d's"?&lt;/P&gt;
&lt;P&gt;But then why does the "int" come first? By that logic it should come last.&lt;/P&gt;
&lt;P&gt;Argh.&amp;nbsp;Maybe option one isn't entirely sensible. Clearly something is not quite&amp;nbsp;perfect with both options. Oh well. Let's move on.&lt;/P&gt;
&lt;P&gt;&lt;U&gt;Consequence Two&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;Now suppose that you wanted to obtain a value in that array, assuming that it had been initialized correctly to have plenty of elements everywhere we need them. How would you do it?&lt;/P&gt;
&lt;P&gt;Suppose we’re in option one. It’s a one-d array. Therefore &lt;SPAN class=code&gt;crazy[10]&lt;/SPAN&gt; is a two-d array. Therefore &lt;SPAN class=code&gt;crazy[10][1, 2]&lt;/SPAN&gt; is an int.&lt;/P&gt;
&lt;P&gt;Suppose we’re in option two. It’s is a two-d array. Therefore &lt;SPAN class=code&gt;crazy[1,2]&lt;/SPAN&gt; is a one-d array. Therefore &lt;SPAN class=code&gt;crazy[1,2][10]&lt;/SPAN&gt; is an int.&lt;/P&gt;
&lt;P&gt;Option one is weird -- crazy is of type &lt;SPAN class=code&gt;int[,][]&lt;/SPAN&gt; but you dereference it as &lt;SPAN class=code&gt;[10][1,2]&lt;/SPAN&gt;! Whereas option two is sensible;&lt;STRONG&gt; the dereferencing syntax exactly matches the ordering of the type name syntax.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;U&gt;Consequence Three&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;Now suppose you want to initialize the “outer” array but are going to fill in the “ragged” interior arrays later. You’ll just keep them set to null at first. What’s the appropriate syntax to initialize the outer array?&lt;/P&gt;
&lt;P&gt;Suppose we’re in option one. It’s a one-d array. Therefore it should be initialized as &lt;SPAN class=code&gt;crazy = new int[,][20]; &lt;/SPAN&gt;right?&lt;/P&gt;
&lt;P&gt;Suppose we’re in option two. It’s a two-d array. Therefore it should be initialized as &lt;SPAN class=code&gt;crazy = new int[][4,5]; &lt;/SPAN&gt;right?&lt;/P&gt;
&lt;P&gt;Option two is weird. We said &lt;SPAN class=code&gt;int[,][]&lt;/SPAN&gt; but initialized it as &lt;SPAN class=code&gt;[][4,5]&lt;/SPAN&gt;. Option one is sensible.&lt;/P&gt;
&lt;P&gt;&lt;U&gt;What C# actually does&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;It’s a mess. No matter which option we choose, something ends up not matching our intuition. Here’s what we actually chose in C#.&lt;/P&gt;
&lt;P&gt;First off: &lt;STRONG&gt;option two is correct&lt;/STRONG&gt;. We force you to live with the weirdness entailed by Consequence One; &lt;STRONG&gt;you do not actually make an element type into an array of that type by appending an array specifier&lt;/STRONG&gt;. You make it into an array type by &lt;EM&gt;prepending the specifier to the list of existing array specifiers&lt;/EM&gt;. Crazy but true.&lt;/P&gt;
&lt;P&gt;This prevents you from having to live with any weirdness from Consequence Two; in this option, the dereferencing happens with the same lexical structure as the declaration.&lt;/P&gt;
&lt;P&gt;What about Consequence Three? This one is the real mind-bender. Neither choice I offered you is correct; apparently I’m a sneaky guy. The &lt;STRONG&gt;correct&lt;/STRONG&gt; way to initialize such an array in C# is:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;crazy = new int[4,5][];&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This is very surprising to people!&lt;/P&gt;
&lt;P&gt;The design principle here is that &lt;STRONG&gt;users expect the lexical structure of the brackets and commas to be consistent across declaration, initialization and dereferencing&lt;/STRONG&gt;. Option two is the best way to ensure that if declaration has the shape &lt;SPAN class=code&gt;[,][]&lt;/SPAN&gt; then the initialization also has that shape, and so does the dereferencing.&lt;/P&gt;
&lt;P&gt;That all said, &lt;STRONG&gt;multidimensional ragged arrays are almost certainly a bad code smell&lt;/STRONG&gt;. Hopefully you will never, ever have to use your new knowledge of these rules in a production environment. &lt;/P&gt;
&lt;P&gt;Life is much better if you can instead use generic collections. It is completely clear what &lt;SPAN class=code&gt;List&amp;lt;int[,]&amp;gt;&lt;/SPAN&gt; means – that’s a list of two-dimensional arrays. Whereas &lt;SPAN class=code&gt;List&amp;lt;int&amp;gt;[,]&lt;/SPAN&gt; means a two-d array of lists of int. &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9846730" 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/Language+Design/default.aspx">Language Design</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Arrays/default.aspx">Arrays</category></item><item><title>Four switch oddities</title><link>http://blogs.msdn.com/ericlippert/archive/2009/08/13/four-switch-oddities.aspx</link><pubDate>Thu, 13 Aug 2009 16:33:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9824596</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>37</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9824596.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9824596</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;The C# switch statement is a bit weird. Today, four quick takes on things you probably didn't know about the switch statement.&lt;/P&gt;
&lt;P&gt;&lt;U&gt;Case 1:&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;You probably know that it is illegal to "fall through" from one switch section to another:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;switch(attitude)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; case Attitude.HighAndMighty:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("High");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // we want to fall through, but this is an error&lt;BR&gt;&amp;nbsp; case Attitude.JustMighty:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("Mighty");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;BR&gt;} &lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;But perhaps you did not know that it is &lt;EM&gt;legal&lt;/EM&gt; to force a fall-through with a &lt;SPAN class=code&gt;goto&lt;/SPAN&gt;:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;switch(attitude)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; case Attitude.HighAndMighty:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("High");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;goto case Attitude.JustMighty;&lt;BR&gt;&amp;nbsp; case Attitude.JustMighty:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("Mighty");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Pretty neat! Cases are semantically just labels to which the switch does a conditional branch; we let you do an explicit branch if you want to.&lt;/P&gt;
&lt;P&gt;&lt;U&gt;Case 2:&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;A common and confusing error that C programmers using C# (like me!) make all the time:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;switch(attitude)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; case Attitude.HighAndMighty:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("High and&amp;nbsp;Mighty");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;BR&gt;&amp;nbsp; case Attitude.JustMighty:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("Just Mighty");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;BR&gt;&amp;nbsp; default:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Do nothing&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;That's an error because in the default case, you "fall through". Admittedly, there is nothing to "fall through" to, but the compiler is picky about this one. It requires that &lt;EM&gt;every&lt;/EM&gt; switch section, &lt;EM&gt;including the last one&lt;/EM&gt;, have an &lt;EM&gt;unreachable end point&lt;/EM&gt;. The purpose of this rule, and of the no-fall-through rule in general, is that we want you to be able to arbitrarily re-order your switch sections without accidentally introducing a breaking change. Fix it by making the "do nothing" explicit with a &lt;SPAN class=code&gt;break&lt;/SPAN&gt; statement.&lt;/P&gt;
&lt;P&gt;This is particularly confusing because&amp;nbsp;some people interpret the error message as saying that the problem is falling &lt;EM&gt;into&lt;/EM&gt; the default case, when actually the problem is that you're falling &lt;EM&gt;out of&lt;/EM&gt; the default case.&lt;/P&gt;
&lt;P&gt;&lt;U&gt;Case 3:&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;As I discussed earlier, a declaration space is a region of code in which two declared things may not have the same name.&amp;nbsp;The &lt;SPAN class=code&gt;foreach&lt;/SPAN&gt; loop implicitly defines its own declaration space, so this is legal:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;foreach(var blah in blahs) { ... }&lt;BR&gt;foreach(var blah in otherblahs) { ...&amp;nbsp;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Switch blocks also define their own declaration spaces, but switch sections do not:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;switch(x)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; case OneWay:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int y = 123;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FindYou(ref y);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;BR&gt;&amp;nbsp; case TheOther:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;double y = 456.7; // illegal!&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; GetchaGetcha(ref y);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;You can solve this problem in a number of ways; the easiest is probably to wrap the body of the switch section in curly braces:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;switch(x)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; case OneWay:&lt;BR&gt;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int y = 123;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FindYou(ref y);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; case TheOther:&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;double y = 456.7; // legal!&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; GetchaGetcha(ref y);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;which tells the compiler "no, &lt;EM&gt;really&lt;/EM&gt;, I want these to be different declaration spaces".&lt;/P&gt;
&lt;P&gt;If you have a variable that you want to declare once and use it in a bunch of different places, that's legal, but a bit strange:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;switch(x)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; case OneDay:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;string s;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SeeYa(out s);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;BR&gt;&amp;nbsp; case NextWeek:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; s = "hello"; // legal, we&amp;nbsp;use the declaration above.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Meetcha(ref s);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;That looks a bit weird, I agree, but it also looks a bit weird to have one switch block with two unbraced competing declarations in it. There are pros and cons of each, the design team had to pick one way or the other, and they chose to have switch cases not define a declaration space.&lt;/P&gt;
&lt;P&gt;&lt;U&gt;Case 4:&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;A funny consequence of the "reachability analysis" rules in the spec is that this program fragment is not legal:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;int M(bool b)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; switch(b)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; case true: return 1; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; case false: return&amp;nbsp;0;&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Of course in reality you would probably write this as the far more concise&amp;nbsp;"return b ? 1 : 0;" but shouldn't that program be &lt;EM&gt;legal&lt;/EM&gt;? It is not, because the reachability analyzer reasons as follows: since there is no "default" case, the switch might choose some option that is not either case. Therefore the end point of the switch is reachable, and therefore we have an int-returning method with a reachable code path that falls off the end of the method without returning.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Yeah, the reachability analyzer is not very smart. It does not realize that there are &lt;EM&gt;only two possible control flows&lt;/EM&gt; and that we've covered all of them with returns. And of course, if you switch on a byte and have cases for each of the 256 possibilities, again, we do not detect that the switch is exhaustive.&lt;/P&gt;
&lt;P&gt;This shortcoming of the language design is silly, but frankly, we have higher priorities than fixing this silly case. If you find yourself in this unfortunate case, just stick a "default:" label onto one of the sections and you'll be fine.&lt;/P&gt;
&lt;P&gt;-- Eric is on vacation; this posting was prerecorded. --&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9824596" 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/Language+Design/default.aspx">Language Design</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/declaration+spaces/default.aspx">declaration spaces</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/reachability/default.aspx">reachability</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/switch+statements/default.aspx">switch statements</category></item><item><title>Iterator Blocks, Part Six: Why no unsafe code?</title><link>http://blogs.msdn.com/ericlippert/archive/2009/07/27/iterator-blocks-part-six-why-no-unsafe-code.aspx</link><pubDate>Mon, 27 Jul 2009 17:07:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9805754</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9805754.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9805754</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;There are three good reasons to disallow unsafe blocks inside an iterator block.&lt;/P&gt;
&lt;P&gt;First, it is an incredibly unlikely scenario. The purpose of iterator blocks is to make it easy to write an&amp;nbsp;iterator that walks over some abstract data type. This is highly likely to be fully managed code; it's simply not a by-design scenario. &lt;/P&gt;
&lt;P&gt;Second, the scenario is a violent mixing of "levels." You think of the level of abstraction of a programming language&amp;nbsp;feature as how "far from the machine" the feature is. Unsafe&amp;nbsp;pointer manipulation is as close to the machine as it gets in C#. You are running without a safety net, poking and peeking at the raw bytes&amp;nbsp;in the&amp;nbsp;virtual memory space of the process. All the protections of&amp;nbsp;verifiable type safety are completely gone and you have total responsibility over every&amp;nbsp;bit in the user-mode address space.&lt;/P&gt;
&lt;P&gt;Iterator blocks, by contrast, are the highest level of abstraction in C# 2.0. There is no immediately obvious mapping from&amp;nbsp;the source code to the generated code; it's a magic box that does the right thing because the compiler is doing&amp;nbsp;some pretty massive transformations on the code, generating&amp;nbsp;classes and implementing interfaces for you. &lt;/P&gt;
&lt;P&gt;Mixing those two levels of abstraction in one method seems like a really bad idea.&lt;/P&gt;
&lt;P&gt;Third, we would have to do some extra work to make "fixed" blocks work correctly, work that would be directly opposed to our guidelines for the correct and efficient use of the "fixed" block. &lt;/P&gt;
&lt;P&gt;I suppose I should briefly explain what the "fixed" block does. When you call unmanaged code that needs to, say, write into the unmanaged address that is the beginning of an array of 16 bit chars, somehow you need to tell the garbage collector&amp;nbsp;"hey, you, GC, running on that other thread over there -- if you get the urge to reorganize memory to be more efficient, I need you to please not move this array for a moment, because unmanaged code on this thread is going to be writing into that address". This operation is called "fixing" or "pinning" the object. &lt;/P&gt;
&lt;P&gt;Clearly it is a bad idea to pin lots of stuff and leave it pinned for a long time. The GC works as well as it does because it is able to reorganize memory to be more efficient; pinning blocks of memory across collections impedes the GC's ability to get work done. We therefore recommend that you pin as little as possible for as little time as possible.&lt;/P&gt;
&lt;P&gt;The CLR provides us two ways to pin something. The hard, flexible, expensive way is to explicitly get a GCHandle on the object, tell the garbage collector "this object is pinned", take the address of the object, do what you need to do, and then unpin it. &lt;/P&gt;
&lt;P&gt;The easy way is to mark a local variable as a "pinned local" using the "fixed" statement. The C# compiler will generate special code that marks the local as "pinned". When the garbage collector does a collection, clearly the GC needs to look at all the locals on the current stack frame, because those locals are all "alive". When the GC sees that a local is pinned, it not only notes that it is alive, it also makes a note to itself that the&amp;nbsp;referent of the contents&amp;nbsp;of this variable are not to be moved during the collection. This is a cheap and easy alternative to explicitly getting a GC handle, but it depends on the variable in question being a local. &lt;/P&gt;
&lt;P&gt;In an iterator block, locals are all realized by hoisting them to&amp;nbsp;fields. Because we cannot pin fields, we'd have to change the code generation for the fixed block so that it took out a handle to the object, pinned it, and ensured that the object was unpinned at some point.&lt;/P&gt;
&lt;P&gt;That's bad enough; now consider what happens when you yield while an object is pinned. Arbitrarily much time could pass between the yield and the unpin! This directly violates our guidance that things should be pinned for as little time as possible.&lt;/P&gt;
&lt;P&gt;For all those reasons, no unsafe code is allowed in iterator blocks. In the unlikely event that you need to dereference pointers in an iterator block, you can always extract the unsafe code to its own helper method and call it from the iterator block.&lt;/P&gt;
&lt;P&gt;***********&lt;/P&gt;
&lt;P&gt;I hope you've enjoyed this little trip into the weird corner cases of iterator blocks. This is a complicated feature with lots of interesting design choice points. &lt;/P&gt;
&lt;P&gt;I'm flying south to Canada to spend some time with my family on the beaver-shark infested shores of the great inland sea known as Lake Huron, so the next few fabulous adventures will be pre-recorded. See you when I'm back.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9805754" 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/Memory+Management/default.aspx">Memory Management</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/Iterators/default.aspx">Iterators</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/unsafe+code/default.aspx">unsafe code</category></item><item><title>Iterator Blocks, Part Five: Push vs Pull</title><link>http://blogs.msdn.com/ericlippert/archive/2009/07/23/iterator-blocks-part-five-push-vs-pull.aspx</link><pubDate>Thu, 23 Jul 2009 17:05:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9805752</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>13</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9805752.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9805752</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;A while back &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2009/06/26/iterators-at-the-summer-games.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/06/26/iterators-at-the-summer-games.aspx"&gt;I posted some commentary I did for the Scripting Summer Games where I noted that there is an isomorphism between "pull" sequences and "push" events.&lt;/A&gt; Normally you think of events as something that "calls you", pushing the event arguments at you. And normally you think of a sequence as something that you "pull from", asking it for the next value until you're done. But you can treat a stream of event firings as being a sequence of event argument objects. And similarly, you could implement a sequence iterator so that it called a method for every object in the collection. &lt;A class="" href="http://msmvps.com/blogs/jon_skeet/archive/2008/01/04/quot-push-quot-linq-revisited-next-attempt-at-an-explanation.aspx" mce_href="http://msmvps.com/blogs/jon_skeet/archive/2008/01/04/quot-push-quot-linq-revisited-next-attempt-at-an-explanation.aspx"&gt;Heck, you could implement all of LINQ on this model if you really wanted.&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;The implementation of iterator blocks is clearly on&amp;nbsp;the "pull" paradigm. It didn't have to be. We could have&amp;nbsp;gone with a sort of "inversion of control" approach.&amp;nbsp;"Pull" iterators have to simulate coroutines with a little state machine that knows how to get back to&amp;nbsp;the state where the code left off. But we already have a mechanism for code to "get back to the state where it left off" -- that's what you do every time you call a method!&amp;nbsp;You remember what you were doing, call the method, and then pick up where you left off. We could have done the same thing with iterators. We could say that this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;void Integers(int length, IObserver&amp;lt;int&amp;gt; observer)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; for (int i = 0; i &amp;lt; length; ++i)&amp;nbsp;yield return i;&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;is a syntactic sugar for&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;void&amp;nbsp;Integers(int length, IObserver&amp;lt;int&amp;gt; observer)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; for (int i = 0; i &amp;lt; length; ++i)&amp;nbsp;observer.Yield(i);&lt;BR&gt;&amp;nbsp; observer.Break();&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;That is, we&amp;nbsp;"raise an event" by calling the observer every time something&amp;nbsp;yields, and raise another event when we're done.&lt;/P&gt;
&lt;P&gt;This would be a much more trivial transformation to&amp;nbsp;make&amp;nbsp;than our current state machine approach, but since most people want sequence iteration on the "pull" model, we do the harder work to make that happen.&lt;/P&gt;
&lt;P&gt;I said this had something to do with exception handling. What's the connection?&lt;/P&gt;
&lt;P&gt;Did you notice something weird about how we handle finally blocks? Consider what happens with the "push model":&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;TextReader&amp;nbsp;reader = File.Open(file);&lt;BR&gt;try&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; blah blah blah yield the lines&lt;BR&gt;}&amp;nbsp;&lt;BR&gt;finally&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; reader.Close();&lt;BR&gt;}&lt;BR&gt;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;If something in the "blah blah blah" is realized as a call to observer.Yield(line), what happens if the code consuming the result throws? Easy. It is just a method call like any other. The call stack unwinds, we find the finally, the file gets closed, everything is good.&lt;/P&gt;
&lt;P&gt;Now suppose this is realized as the MoveNext of a "pull" iterator. What happens when the code that is consuming the result throws? If we're consuming the result then we've &lt;EM&gt;returned&lt;/EM&gt; from the call to MoveNext! There is no "try", there is no "finally". And yet usually the finally gets executed anyways! If the code that is consuming the results throws, odds are good that it was in a foreach; when foreach throws, the enumerator is disposed, and when the enumerator is disposed, we figure out which "finallys" were around when we last left MoveNext, and we run a special method that does whatever was in the pending finally blocks.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;This is pretty weird.&lt;/EM&gt; What's going on here is that for finally blocks, "pull" iterators have the same semantics as "push" iterators. When you yield from a try containing a finally, it looks like the finally is still "on the stack" and runs when the consumer throws.&lt;/P&gt;
&lt;P&gt;So what if the try block has a catch?&lt;/P&gt;
&lt;P&gt;The original designers of C# 2.0 -- and remember, this is long before my time on the team -- had a huge debate over this. A debate which was repeated in miniature when I sent them all an&amp;nbsp;email asking for the justification for this decision. There are three basic positions:&lt;/P&gt;
&lt;P&gt;1) Do not allow yield returns in try blocks at all.&amp;nbsp;(Or blocks that are sugars for try blocks, like using blocks.) Use some other mechanism other than "finally" to express the idea of "this is the code that you run when the caller shuts down the enumeration."&lt;/P&gt;
&lt;P&gt;2) Allow yield returns in all try blocks.&lt;/P&gt;
&lt;P&gt;3) Allow yield returns in try blocks that have finally blocks, but not if they have&amp;nbsp;catch blocks.&lt;/P&gt;
&lt;P&gt;The down sides of (1)&amp;nbsp;are that you have to come up with some syntax for representing the "finally" logic that isn't actually a "finally", and that it becomes more difficult to iterate over stuff that requires cleanup, like iterating over the contents of a file. This makes the feature both confusing and weak; we should avoid this option if at all possible.&lt;/P&gt;
&lt;P&gt;The down side of (2) is that the exception handling behaviour beomes deeply, weirdly inconsistent between finally blocks and catch blocks. If you have a&amp;nbsp;yield in a try block with a finally, and the consumer of the iteration throws, then the finally runs, as though you were on the "push" model. But if you have a yield&amp;nbsp;in a try block with a catch, and the consumer of the iteration throws, then the catch does not run, because its not on the call stack. Users have a reasonable expectation that finally and catch work more or less the same way when an exception happens; that is, that control will be consistently transferred to&amp;nbsp;a matching catch or the finally.&lt;/P&gt;
&lt;P&gt;The down side of (3) is that the rule seems arbitrary and weird -- until you read five unnecessarily prolix blog entries that explain what on earth the design team was thinking.&lt;/P&gt;
&lt;P&gt;Obviously, they picked (3), and now you know why.&lt;/P&gt;
&lt;P&gt;Next time, we'll finish up this series with a look at unsafe code.&amp;nbsp;Now that you know all this stuff, seeing why there's no unsafe code allowed in an iterator block is pretty straightforward by comparison.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9805752" 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/Language+Design/default.aspx">Language Design</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Iterators/default.aspx">Iterators</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/exception+handling/default.aspx">exception handling</category></item><item><title>Iterator blocks Part Four: Why no yield in catch?</title><link>http://blogs.msdn.com/ericlippert/archive/2009/07/20/iterator-blocks-part-four-why-no-yield-in-catch.aspx</link><pubDate>Mon, 20 Jul 2009 16:44:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9804035</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>14</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9804035.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9804035</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Now that you know why we disallow yielding in a finally, it’s pretty straightforward to see why we also disallow yielding in a catch. &lt;/P&gt;
&lt;P&gt;First off, we still have the problem that it is illegal to “goto” into the middle of the handler of a try-protected region. The &lt;STRONG&gt;only&lt;/STRONG&gt; way to enter a catch block is via the “non-local goto” that is catching an exception. So once you yielded out of the catch block, the next time MoveNext was called, we’d have no way to get back into the catch block where we left off.&lt;/P&gt;
&lt;P&gt;Second, the exception that was thrown and caught is an intrinsic part of the execution of the catch block because it can be re-thrown using the “empty throw” syntax. We have no way of preserving that state across calls to MoveNext. &lt;/P&gt;
&lt;P&gt;I suppose that we could in theory allow yields inside catch blocks that do not have an “empty throw”. We could turn this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;try &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp; M(); &lt;BR&gt;}&lt;BR&gt;catch(Exception x)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; yield return x.ToString().Length;&lt;BR&gt;&amp;nbsp; yield return 123;&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;into&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;switch(this.state)&lt;BR&gt;{&lt;BR&gt;case 0: goto LABEL0;&lt;BR&gt;case 1: goto LABEL1;&lt;BR&gt;case 2: goto LABEL2;&lt;BR&gt;}&lt;BR&gt;LABEL0:&lt;BR&gt;try &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp; M();&amp;nbsp;&lt;BR&gt;&amp;nbsp; this.state = 2;&lt;BR&gt;&amp;nbsp; goto LABEL2;&lt;BR&gt;}&lt;BR&gt;catch(Exception x)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; this.x = x;&amp;nbsp; &lt;BR&gt;}&lt;BR&gt;this.current = this.x.ToString().Length;&lt;BR&gt;this.state = 1;&lt;BR&gt;return true;&lt;BR&gt;LABEL1:&lt;BR&gt;this.current = 123;&lt;BR&gt;this.state = 2;&lt;BR&gt;return true;&lt;BR&gt;LABEL2:&lt;BR&gt;return false;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;But frankly, that would be pretty weird. It would feel like a very odd restriction to disallow a fundamental part of the “catch” syntax. &lt;/P&gt;
&lt;P&gt;And really, what’s the usage case that motivates this situation in the first place? Do people really want to try something and then yield a bunch of results if it fails? I suppose you could do something like:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;IEnumerable&amp;lt;string&amp;gt; GetFooStrings(Foo foo)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; try&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return Foo.Bar();&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; catch(InvalidFooException x)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return "";&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;… etc.&lt;BR&gt;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;but there are lots of ways to easily rewrite this so that you don’t have to yield in a catch:&lt;/P&gt;&lt;SPAN class=code&gt;IEnumerable&amp;lt;string&amp;gt; GetFooStrings(Foo foo)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; string result;&lt;BR&gt;&amp;nbsp; try&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = Foo.Bar();&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; catch(InvalidFooException x)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = "";&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; yield return result;&lt;BR&gt;… etc.&lt;BR&gt;&lt;/SPAN&gt;
&lt;P&gt;Since there are usually easy workarounds, and we would have to put crazy-seeming restrictions on the use of re-throws, it’s easier to simply say “no yields inside a catch”.&lt;/P&gt;
&lt;P&gt;We still haven’t explained why it is &lt;EM&gt;illegal&lt;/EM&gt; to yield inside a try that has a catch, nor why it is &lt;EM&gt;legal&lt;/EM&gt; to yield inside a try that has a finally. To understand why, next time I’ll need to muse about the duality between sequences and events. &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9804035" 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/Language+Design/default.aspx">Language Design</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Iterators/default.aspx">Iterators</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/exception+handling/default.aspx">exception handling</category></item><item><title>Iterator Blocks, Part Three: Why no yield in finally?</title><link>http://blogs.msdn.com/ericlippert/archive/2009/07/16/iterator-blocks-part-three-why-no-yield-in-finally.aspx</link><pubDate>Thu, 16 Jul 2009 16:18:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9798914</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>10</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9798914.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9798914</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;There are three scenarios in which code could be executing in a finally in an iterator block. In none of them is it a good idea to yield a value from inside the finally, so this is illegal across the board. The three scenarios are (1) normal cleanup, (2) exception cleanup, and (3) iterator disposal.&lt;/P&gt;
&lt;P&gt;For the first scenario, suppose we have something like&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;try&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; Setup();&lt;BR&gt;&amp;nbsp; yield return M();&lt;BR&gt;}&lt;BR&gt;finally&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; yield return N();&lt;BR&gt;&amp;nbsp; Cleanup();&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;How should we transform this into an iterator state machine? Naively, we want to do something like:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;switch (this.state)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; case 0: goto LABEL0;&lt;BR&gt;&amp;nbsp; case 1: goto LABEL1:&lt;BR&gt;&amp;nbsp; case 2: goto LABEL2:&lt;BR&gt;&amp;nbsp; case 3: goto LABEL3:&lt;BR&gt;}&lt;BR&gt;LABEL0:&lt;BR&gt;try&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; Setup();&lt;BR&gt;&amp;nbsp; this.current = M();&lt;BR&gt;&amp;nbsp; this.state = 1;&lt;BR&gt;&amp;nbsp; return true; // BUT DON'T RUN THE FINALLY!&lt;BR&gt;LABEL1:&lt;BR&gt;}&lt;BR&gt;finally&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; this.current = N();&lt;BR&gt;&amp;nbsp; this.state = 2;&lt;BR&gt;&amp;nbsp; return true;&lt;BR&gt;LABEL2:&lt;BR&gt;&amp;nbsp; Cleanup();&lt;BR&gt;}&lt;BR&gt;LABEL3:&lt;BR&gt;this.state = 3;&lt;BR&gt;return false;&lt;BR&gt;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;There's an immediate problem with this: we both "goto" into a finally block and "return" out of one. Neither&amp;nbsp;is legal. &lt;/P&gt;
&lt;P&gt;Leaving a finally block via "return" is illegal because it is weird. Suppose the try block returns, causing the finally to execute. What happens when the finally block returns? The original return value&amp;nbsp;would be&amp;nbsp;lost and some other return value&amp;nbsp;would be&amp;nbsp;substituted for it.&amp;nbsp;This seems bizarre and bug-prone, so its not legal; you cannot exit a finally via return. And of course, you don't want the finally to run after the return in the try in this case!&lt;/P&gt;
&lt;P&gt;Furthermore,&amp;nbsp;in the CLR model of exception handling it is illegal to branch via a goto into a try block or its "handler" (that is, the catch or finally clause). Nor can you branch out of the handler.&amp;nbsp;These special&amp;nbsp;regions have special code that needs to be run when the region is entered and exited; you cannot skip&amp;nbsp;either with a goto. &lt;/P&gt;
&lt;P&gt;So we have no immediately obvious way to generate verifiable code for this scenario. Right off the bat, we have a huge number of points against this feature; we'd have to either convince the CLR guys to allow spaghetti code involving protected regions, or come up with some clever technique for generating this code.&lt;/P&gt;
&lt;P&gt;And that's just the scenario where nothing is going wrong yet! Suppose a miracle happens and we manage to successfully generate code for scenario one. Now consider our second scenario, where M throws exception X. Remember, the finally block "catches" the exception and processes the cleanup code. If the cleanup code throws, then the original exception is discarded and the new processing of the new exception takes over. If the cleanup code succeeds, then the original exception continues to be "thrown" up the call stack, looking for more finally blocks or catch blocks.&lt;/P&gt;
&lt;P&gt;Suppose the cleanup code does not throw. What should the control flow look like? The caller calls MoveNext for the first time. M() throws X. The finally block takes over. The finally block calls N(), and returns control to the caller with the results of N() !? What happened to X, the exception? Is it just waiting there, in limbo? When the second call to MoveNext happens, should the cleanup code get run then, and X suddenly pops back into existence and continues to be thrown up the stack? That makes no sense at all; &lt;STRONG&gt;the two calls to MoveNext could have had completely different stacks&lt;/STRONG&gt;! This is crazy, plus we have no mechanism at all in the CLR for these kind of shenanigans.&lt;/P&gt;
&lt;P&gt;Third, suppose we manage to solve all these problems. Now consider what happens when the caller calls MoveNext, M() succeeds, control returns to the caller, and the caller calls an early Dispose() on the enumerator. (I guess they wanted only one item.) We generate a Dispose method that checks the current state and executes any pending finally blocks. What the heck is the Dispose method supposed to do when it encounters the yield return in the pending finally block? We're not even in a call to MoveNext anymore! Should we call N() and ignore the result? Should we return from the Dispose() after the call to N(), or do the cleanup and then return? What exactly should the control flow do here? We're in a context where &lt;EM&gt;we might not even be iterating anymore, and yet we're still yielding.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;It really doesn't make any logical sense to do a yield return in this scenario; we're possibly not in a position where the caller is expecting things to continue to be yielded to it.&lt;/P&gt;
&lt;P&gt;So in short, we'd have to do at least two impossible things in order to enable a scenario that makes no sense in the first place. If ever a feature called out to be cut at the design phase, this is it. Therefore: no yields inside finally blocks. Thank goodness for that.&lt;/P&gt;
&lt;P&gt;Next time: now that you know all that, figuring out "why no yields inside catch blocks" is pretty straightforward.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9798914" 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/Language+Design/default.aspx">Language Design</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Iterators/default.aspx">Iterators</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/exception+handling/default.aspx">exception handling</category></item></channel></rss>