<?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 : Conversions</title><link>http://blogs.msdn.com/ericlippert/archive/tags/Conversions/default.aspx</link><description>Tags: Conversions</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>What's the difference between "as" and "cast" operators?</title><link>http://blogs.msdn.com/ericlippert/archive/2009/10/08/what-s-the-difference-between-as-and-cast-operators.aspx</link><pubDate>Thu, 08 Oct 2009 16:36:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9900307</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>34</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9900307.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9900307</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Most people will tell you that the difference between "&lt;SPAN class=code&gt;(Alpha) bravo&lt;/SPAN&gt;" and "&lt;SPAN class=code&gt;bravo as Alpha&lt;/SPAN&gt;" is that the former throws an exception if the conversion fails, whereas the latter returns null. Though this is correct, and this is the most obvious difference, it's not the only difference. There are pitfalls to watch out for here.&lt;/P&gt;
&lt;P&gt;First off, since the result of the "as" operator can be null, the resulting type has to be one that takes a null value: either a reference type or a nullable value type. You cannot do "as int", that doesn't make any sense. If the argument isn't an int, then what should the return value be? The type of the "as" expression is always the named type so it needs to be a type that can take a null.&lt;/P&gt;
&lt;P&gt;Second, &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx"&gt;the cast operator, as I've discussed before, is a strange beast&lt;/A&gt;. It means two contradictory things: "check to see if this object really is of this type, throw if it is not" and "this object is not of the given type; find me an equivalent value that belongs to the given type". The latter meaning of the cast operator is not shared by the "as" operator. If you say&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;short s = (short)123;&lt;BR&gt;int? i = s as int?;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;then you're out of luck. The "as" operator will not make the representation-changing conversions from short to nullable int like the cast operator would. Similarly, if you have class Alpha and unrelated class Bravo, with a user-defined conversion from Bravo to Alpha, then "&lt;SPAN class=code&gt;(Alpha) bravo&lt;/SPAN&gt;" will run the user-defined conversion, but "&lt;SPAN class=code&gt;bravo as Alpha&lt;/SPAN&gt;" will not. The "as" operator only considers reference, boxing and unboxing conversions.&lt;/P&gt;
&lt;P&gt;And finally, of course the use cases of the two operators are superficially similar, but semantically quite different. A cast communicates to the reader "I am certain that this conversion is legal and I am willing to take a runtime exception if I'm wrong". The "as" operator communicates "I don't know if this conversion is legal or not; we're going to give it a try and see how it goes". &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9900307" 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/Conversions/default.aspx">Conversions</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/cast+operator/default.aspx">cast operator</category></item><item><title>Why does char convert implicitly to ushort but not vice versa?</title><link>http://blogs.msdn.com/ericlippert/archive/2009/10/01/why-does-char-convert-implicitly-to-ushort-but-not-vice-versa.aspx</link><pubDate>Thu, 01 Oct 2009 19:53:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9901940</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>17</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9901940.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9901940</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;&lt;A href="http://stackoverflow.com/questions/1503430/implicit-type-cast-in-c/1504959#1504959" mce_href="http://stackoverflow.com/questions/1503430/implicit-type-cast-in-c/1504959#1504959"&gt;Another good question from StackOverflow&lt;/A&gt;. Why is there an implicit conversion from char to ushort, but only an explicit conversion from ushort to char? Why did the designers of the language believe that these asymmetrical rules were sensible rules to add to the language?&lt;/P&gt;
&lt;P&gt;Well, first off, the obvious things which would &lt;EM&gt;prevent&lt;/EM&gt; either conversion from being implicit do not apply. A char is implemented as an unsigned 16 bit integer that represents a character in a UTF-16 encoding, so it can be converted to or from a ushort without loss of precision, or, for that matter, without change of representation. The runtime simply goes from treating this bit pattern as a char to treating the same bit pattern as a ushort, or vice versa.&lt;/P&gt;
&lt;P&gt;It is therefore &lt;EM&gt;possible&lt;/EM&gt; to allow either implicit conversion. Now, just because something is possible does not mean it is a good idea. Clearly the designers of the language thought that implicitly converting char to ushort was a good idea, but implicitly converting ushort to char is not. (And since char to ushort is a good idea, it seems reasonable that char-to-anything-that-ushort-goes-to is also reasonable, hence, char to int is also good.)&lt;/P&gt;
&lt;P&gt;Unlike you guys, I have the original notes from the language design team at my disposal. Digging through those, we discover some interesting facts.&lt;/P&gt;
&lt;P&gt;The conversion from ushort to char is covered in the notes from April 14th, 1999, where the question of whether it should be legal to convert from byte to char arises. &lt;STRONG&gt;In the original pre-release version of C#, this was legal for a brief time.&lt;/STRONG&gt; I've lightly edited the notes to make them clear without an understanding of 1999-era pre-release Microsoft code names. I've also added emphasis on important points:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;[The language design committee] has chosen to provide an implicit conversion from bytes to chars, since the domain of one is completely contained by the other. Right now, however, [the runtime library authors] only provide Write methods which take chars and ints, which means that bytes print out as characters since that ends up being the best method. We can solve this either by providing more methods on the writer class or by removing the implicit conversion. &lt;/P&gt;
&lt;P&gt;There is an argument for why the latter is the correct thing to do. After all, &lt;STRONG&gt;bytes really aren't characters&lt;/STRONG&gt;. True, there may be a &lt;EM&gt;useful mapping&lt;/EM&gt; from bytes to chars, but ultimately, &lt;STRONG&gt;23 does not denote the same thing as the character with ASCII value 23, in the same way that the byte 23 denotes the same thing as the long 23&lt;/STRONG&gt;. Asking [the library authors] to provide this additional method simply because of how a quirk in our type system works out seems rather weak.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The notes then conclude with the decision that byte-to-char should be an explicit conversion, and integer-literal-in-range-of-char should also be an explicit conversion.&lt;/P&gt;
&lt;P&gt;Note that the language design notes do not call out why ushort-to-char was also made explicit at the same time, but you can see that the same logic applies. When passing a ushort to a method overloaded as M(int) and M(char), odds are good that you want to treat the ushort as a number, not as a character. And a ushort is not a character representation in the same way that a ushort is a numeric representation, so it seems reasonable to make that conversion explicit as well.&lt;/P&gt;
&lt;P&gt;The decision to make char go to ushort implicitly was made on the 17th of September, 1999; the design notes from that day on this topic simply state "char to ushort is also a legal implicit conversion", and that's it. No further exposition of what was going on in the language designers' heads that day is evident in the notes. &lt;/P&gt;
&lt;P&gt;However, we can make &lt;EM&gt;educated guesses&lt;/EM&gt; as to why implicit char-to-ushort was considered a good idea. The key idea here is that the conversion from number to character is a "possibly dodgy" conversion. It's taking something that you do not know is intended to be a character, and choosing to treat it as one. That seems like the sort of thing you want to call out that you are doing explicitly, rather than accidentally allowing it. But the reverse is much less dodgy. There is a long tradition in C programming of treating characters as integers -- to obtain their underlying values, or to do mathematics on them. &lt;/P&gt;
&lt;P&gt;In short: it seems reasonable that using a number as a character could be an accident and a bug, but it also seems reasonable that using a character as a number is deliberate and desirable. This asymmetry is therefore reflected in the rules of the language.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9901940" 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/Conversions/default.aspx">Conversions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/integer+arithmetic/default.aspx">integer arithmetic</category></item><item><title>Why do ref and out parameters not allow type variation?</title><link>http://blogs.msdn.com/ericlippert/archive/2009/09/21/why-do-ref-and-out-parameters-not-allow-type-variation.aspx</link><pubDate>Mon, 21 Sep 2009 16:36:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9895925</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>16</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9895925.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9895925</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Here's a &lt;A class="" href="http://stackoverflow.com/questions/1207144/c-why-doesnt-ref-and-out-support-polymorphism/1207302#1207302" mce_href="http://stackoverflow.com/questions/1207144/c-why-doesnt-ref-and-out-support-polymorphism/1207302#1207302"&gt;good question from StackOverflow&lt;/A&gt;:&lt;/P&gt;
&lt;P&gt;If you have a method that takes an "X" then you have to pass an expression of type X &lt;STRONG&gt;or something convertible to X&lt;/STRONG&gt;. Say, an expression of a type derived from X. But if you have a method that takes a "ref X", you have to pass a ref to a variable of type X, period. Why is that? Why not allow the type to vary, as we do with non-ref calls?&lt;/P&gt;
&lt;P&gt;Let's suppose you have classes Animal, Mammal, Reptile, Giraffe, Turtle and Tiger, with the obvious subclassing relationships.&lt;/P&gt;
&lt;P&gt;Now suppose you have a method void M(ref Mammal m). M can both read and write m. Can you pass a variable of type Animal to M? No. That would not be safe. That variable could contain a Turtle, but M will assume that it contains only Mammals. A Turtle is not a Mammal.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Conclusion 1&lt;/STRONG&gt;: Ref parameters cannot be made "bigger". (There are more animals than mammals, so the variable is getting "bigger" because it can contain more things.)&lt;/P&gt;
&lt;P&gt;Can you pass a variable of type Giraffe to M? No. M can write to m, and M might want to write a Tiger into m. Now you've put a Tiger into a variable which is actually of type Giraffe.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Conclusion 2&lt;/STRONG&gt;: Ref parameters cannot be made "smaller".&lt;/P&gt;
&lt;P&gt;Now consider N(out Mammal n).&lt;/P&gt;
&lt;P&gt;Can you pass a variable of type Giraffe to N? No. As with our previous example, N can write to n, and N might want to write a Tiger. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Conclusion 3&lt;/STRONG&gt;: Out parameters cannot be made "smaller".&lt;/P&gt;
&lt;P&gt;Can you pass a variable of type Animal to N?&lt;/P&gt;
&lt;P&gt;Hmm.&lt;/P&gt;
&lt;P&gt;Well, why not? N cannot read from n, it can only write to it, right? You write a Tiger to a variable of type Animal and you're all set, right?&lt;/P&gt;
&lt;P&gt;Wrong. The rule is not "N can only write to n". The rules are, briefly: &lt;/P&gt;
&lt;P&gt;1) N has to write to n before N returns normally. (If N throws, all bets are off.)&lt;BR&gt;2) N has to write something to n &lt;EM&gt;before it reads something from n&lt;/EM&gt;.&lt;/P&gt;
&lt;P&gt;That permits this sequence of events:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Declare a field x of type Animal. &lt;/LI&gt;
&lt;LI&gt;Pass x as an out parameter to N. &lt;/LI&gt;
&lt;LI&gt;N writes a Tiger into n, which is an alias for x. &lt;/LI&gt;
&lt;LI&gt;On another thread, someone writes a Turtle into x. &lt;/LI&gt;
&lt;LI&gt;N attempts to read the contents of n, and discovers a Turtle in what it thinks is a variable of type Mammal.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;That scenario -- using multithreading to write into a variable that has been aliased&amp;nbsp;--&amp;nbsp;is awful and you should never do it, but it is possible.&lt;/P&gt;
&lt;P&gt;UPDATE: Commenter Pavel Minaev correctly notes that there is no need for multithreading to cause mayhem. We could replace that fourth step with&lt;/P&gt;
&lt;LI&gt;N makes a call to a method which directly or indirectly causes some code to write a Turtle into x.&lt;/LI&gt;
&lt;P&gt;Regardless of how the variable's contents&amp;nbsp;might get altered, clearly we want to make the type system violation illegal. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Conclusion 4&lt;/STRONG&gt;: Out parameters cannot be made "larger".&lt;/P&gt;
&lt;P&gt;There is another argument which supports this conclusion:&amp;nbsp;"out" and "ref" are actually exactly the same&amp;nbsp;behind the scenes.&amp;nbsp;The CLR only supports "ref"; "out" is just "ref" where the compiler enforces slightly different rules&amp;nbsp;regarding when the variable in question is known to have been definitely assigned. That's why it is illegal to make method overloads that differ solely in out/ref-ness; the CLR cannot tell them apart! Therefore the rules for type safety for out have to be the same as for ref.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Final conclusion&lt;/STRONG&gt;: Neither ref nor out parameters may vary&amp;nbsp;in type at the call site. To do otherwise is to break verifiable type safety.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9895925" 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/Conversions/default.aspx">Conversions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx">Covariance and Contravariance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/type+safety/default.aspx">type safety</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/reference/default.aspx">reference</category></item><item><title>Not everything derives from object</title><link>http://blogs.msdn.com/ericlippert/archive/2009/08/06/not-everything-derives-from-object.aspx</link><pubDate>Thu, 06 Aug 2009 16:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9820268</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>43</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9820268.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9820268</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;I hear a lot of myths about C#. Usually the myths have some germ of truth to them, like "&lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx"&gt;value types are always allocated on the stack&lt;/A&gt;". If you replace "always" with "sometimes", then the incorrect mythical statement becomes correct.&lt;/P&gt;
&lt;P&gt;One I hear quite frequently is "in C# every type derives from object". Not true! &lt;/P&gt;
&lt;P&gt;First off, no pointer types derive from object, nor are any of them convertible to object. Unsafe pointer types are explicitly outside of the normal type rules for the language. (If you want to treat a pointer as a value type, convert it to System.IntPtr, and then you can use it as a value type.)&amp;nbsp;We'll leave pointer types aside for the rest of this discussion.&lt;/P&gt;
&lt;P&gt;A great many types do derive from object. All value types,&amp;nbsp;including enums and nullable types,&amp;nbsp;derive from object. All class, array and delegate types derive from object.&lt;/P&gt;
&lt;P&gt;These are all the "concrete" types; every object instance that you actually encounter in the wild will be either null, or a class, delegate, array, struct, enum or nullable value type. So it would be correct, though tautological, to say that all object instances derive from object. But that wasn't the myth; the myth stated was that all &lt;EM&gt;types&lt;/EM&gt; are derived from object. &lt;/P&gt;
&lt;P&gt;Interface types, not being classes, are not derived from object. They are all &lt;EM&gt;convertible&lt;/EM&gt; to object, to be sure, because we know that at runtime the instance will be a concrete type. But interfaces only derive from other interface types, and object is not an interface type.&lt;/P&gt;
&lt;P&gt;"Open" type parameter types are also not derived from object. They are, to be sure, types. You can make a field whose type is a type parameter type. And since generic types and methods ultimately are only ever used at runtime when fully "constructed" with "concrete" type arguments, type parameter types are always &lt;EM&gt;convertible&lt;/EM&gt; to object. (This is why you cannot make an IEnumerable&amp;lt;void*&amp;gt; -- we require that the type argument be convertible to object.) Type parameter types are not derived from anything; they have an "effective base class", so that type arguments are constrained to be derived from the effective base class, but they themselves are not "derived" from anything.&lt;/P&gt;
&lt;P&gt;The way to correct this myth is to simply replace "derives from" with "is convertible to", and to ignore pointer types: &lt;STRONG&gt;every non-pointer type in C# is &lt;EM&gt;convertible &lt;/EM&gt;to object.&lt;/STRONG&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9820268" 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/Conversions/default.aspx">Conversions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Value+Types/default.aspx">Value Types</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/myths/default.aspx">myths</category></item><item><title>The void is invariant</title><link>http://blogs.msdn.com/ericlippert/archive/2009/06/29/the-void-is-invariant.aspx</link><pubDate>Mon, 29 Jun 2009 17:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9756024</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>19</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9756024.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9756024</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;[UPDATES below]&amp;nbsp;&lt;/P&gt;
&lt;P&gt;A while back I described &lt;A href="http://blogs.msdn.com/ericlippert/archive/2007/10/19/covariance-and-contravariance-in-c-part-three-member-group-conversion-variance.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/10/19/covariance-and-contravariance-in-c-part-three-member-group-conversion-variance.aspx"&gt;a kind of variance that we’ve supported since C# 2.0.&lt;/A&gt; When assigning a method group to a delegate type, such that both the selected method and the delegate target agree that their return type is a reference type, then the conversion is allowed to be covariant. That is, you can say:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;Giraffe GetGiraffe() { … }&lt;BR&gt;…&lt;BR&gt;Func&amp;lt;Animal&amp;gt; f = GetGiraffe;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This works logically because anyone who calls f must be able to handle any animal that comes back. The actual method claims to only return animals, and in fact, makes the stronger claim to only return giraffes. &lt;/P&gt;
&lt;P&gt;This works out in the CLR because the bits that make up a reference to an instance of Giraffe are exactly the same bits that make up a reference to that Giraffe interpreted as an instance of Animal. We can allow this magical conversion to happen because the CLR guarantees that it will all just work out without going in there and having to futz around with the bits.&lt;/P&gt;
&lt;P&gt;This is why this trick only works with reference types. A method that returns, say, a double cannot be converted via a covariant conversion to a delegate type that expects the method to return an object. Somewhere there would have to be code emitted that takes the returned double and boxes it to object; the bits of a double and the bits of a reference to an object boxing a double are completely different.&lt;/P&gt;
&lt;P&gt;But why doesn’t this trick work with void types? Here we have a method that returns some sort of success or failure code. Maybe we don’t care what it returns.&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;static bool DoSomething(bool b)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; if (b) return DoTheThing();&lt;BR&gt;&amp;nbsp; else return DoTheOtherThing();&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;Action&amp;lt;bool&amp;gt; action = DoSomething;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This doesn’t work. Why not? The caller of the action is not even going to &lt;EM&gt;use&lt;/EM&gt; the returned value, so it doesn’t matter one bit what it is! Shouldn’t “void” be considered &lt;EM&gt;a supertype of all possible types&lt;/EM&gt; for the purposes of covariant return type conversions from method groups to delegate types?&lt;/P&gt;
&lt;P&gt;No, and I’ll tell you why.&lt;/P&gt;
&lt;P&gt;Consider what happens when you do this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;bool x = DoSomething(true);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;We spit out IL that does the following:&lt;/P&gt;
&lt;P&gt;(1) put true on the IL stack – the stack gets one deeper&lt;BR&gt;(2) call DoSomething – the argument is removed from the stack and the return value is placed on the stack.&amp;nbsp; Net, the stack stays the same size as before&lt;BR&gt;(3) stuff whatever on top of the stack into local variable x – the stack now returns to its original depth.&lt;/P&gt;
&lt;P&gt;Now consider what happens when you do this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;DoSomething(true);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;We spit out IL that does the first two steps as before. But we cannot stop there! There is now a bool on the IL stack which needs to be removed. We generate a pop instruction to represent the fact that the returned bool has been discarded.&lt;/P&gt;
&lt;P&gt;Now consider what happens when you do this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;action(true);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;The compiler believes that action is a void-returning method, so it does not generate a pop instruction. If we allowed you to stuff DoSomething into the action, then we would be allowing you to misalign the IL stack!&lt;/P&gt;
&lt;P&gt;But didn’t I say “&lt;A href="http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx"&gt;the stack is an implementation detail?&lt;/A&gt;” Yes, but &lt;EM&gt;that’s a different stack&lt;/EM&gt;. The CLI specification describes a “virtual machine” which passes around arguments and returned values on a stack. An implementation of the CLI is required to make something that behaves like the specified machine, but it is not required to do so in any particular manner. It is not required to use the million-bytes-per-thread stack supplied to each thread by the operating system as its implementation of the IL stack; that’s a convenient structure to use, of course, but it’s an implementation detail that it does so.&lt;/P&gt;
&lt;P&gt;(As an aside: when we implemented the script engines, we also first specified our own private stack-based virtual machine. When we implemented it, we decided to put the information about “return addresses” – that is, “what code do I run next?” on the system stack, but we put arguments and return values of script functions in a stack-shaped block of memory that we allocated on our own. This made building the JScript garbage collector easier.)&lt;/P&gt;
&lt;P&gt;In practice, the jitter uses the system stack for some things and registers for other things. Return values are actually often sent back in a register, not on the stack. But that implementation detail doesn’t help us out when deciding what the conversion rules are; we have to assume that the implementation can do no more than what the CLI specification says. Had the CLI specification said “the returned value of any function is passed back in a ‘virtual register’” rather than having it pushed onto the stack, then we could have made void-returning delegates compatible with functions that returned anything. You can always just ignore the value in the register. But that’s not what the CLI specified, so that’s not what we can do. &lt;/P&gt;
&lt;P&gt;[UPDATE]&lt;/P&gt;
&lt;P&gt;A number of people have asked in the comments why we do not simply generate a helper method that does what you want. That is, when you say&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;Action&amp;lt;bool&amp;gt; action = DoSomething;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;realize that as&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;static&amp;nbsp;void DoSomethingHelper(bool b)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp; bool result = DoSomething(b); // result is ignored&lt;BR&gt;}&lt;BR&gt;...&lt;BR&gt;Action&amp;lt;bool&amp;gt; action = DoSomethingHelper;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;We could do that. But where would you like the line to be drawn? Should you be able to assign a&amp;nbsp;reference to a method that returns an int to a Func&amp;lt;Nullable&amp;lt;int&amp;gt;&amp;gt;? We could spit a helper method that converts the int to a nullable int.&amp;nbsp;What about Func&amp;lt;double&amp;gt;? We could spit a helper method that converts the int to a double. What about Func&amp;lt;object&amp;gt;? We could spit a helper method that boxes the int, unexpectedly allocating memory off the heap every time you call it. What about a Func&amp;lt;Foo&amp;gt; where there is a user-defined implicit conversion from int to Foo?&lt;/P&gt;
&lt;P&gt;We could be spitting arbitrarily complex fixer-upper methods that would seamlessly "do what you meant to say", and we have to stop somewhere.&amp;nbsp;The exact semantics of what we&amp;nbsp;do and do not&amp;nbsp;fix up would have to be designed, specified, implemented, tested, documented, shipped to customers and maintained forever. Those are costs. Plus, &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/08/31/future-breaking-changes-part-two.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/08/31/future-breaking-changes-part-two.aspx"&gt;every time we add a new conversion rule to the language we add breaking changes&lt;/A&gt;. The costs of those breaking changes to our customers have to be factored in.&lt;/P&gt;
&lt;P&gt;But more fundamentally, one of the design principles of C# is "if &lt;STRONG&gt;you say something wrong then &lt;EM&gt;we tell you&lt;/EM&gt; rather than trying &lt;EM&gt;to guess what you meant&lt;/EM&gt;&lt;/STRONG&gt;". JScript is deliberately a "muddle on through and do the best you can" language; C# is not. If what you want to do is make a delegate to a helper method then you express that intention by going right ahead and making that method.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9756024" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Scripting/default.aspx">Scripting</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Code+Generation/default.aspx">Code Generation</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Conversions/default.aspx">Conversions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx">Covariance and Contravariance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Memory+Management/default.aspx">Memory Management</category></item><item><title>Representation and Identity</title><link>http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx</link><pubDate>Thu, 19 Mar 2009 16:46:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9488368</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>23</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9488368.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9488368</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;I get a fair number of questions about the C# cast operator. The most frequent question I get is:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;short sss = 123;&lt;BR&gt;object ooo = sss;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Box the short.&lt;BR&gt;int iii = (int) sss;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Perfectly legal.&lt;BR&gt;int jjj = (int) (short) ooo; // Perfectly legal&lt;BR&gt;int kkk = (int) ooo;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Invalid cast exception?! Why?&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Why? Because a boxed T can only be unboxed to T. (*) Once it is unboxed, it’s just a value that can be cast as usual, so the double cast works just fine. &lt;/P&gt;
&lt;P&gt;Many people find this restriction grating; they expect to be able to cast a boxed thing to &lt;EM&gt;anything&lt;/EM&gt; that the unboxed thing could have been cast to. There are ways to do that, as we’ll see, but there are good reasons why the cast operator does what it does.&lt;/P&gt;
&lt;P&gt;To understand why this design works this way it’s necessary to first wrap your head around the contradiction that is the cast operator. There are two (¤) basic usages of the cast operator in C#:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;My code has an expression of type B, but I happen to have more information than the compiler does. I claim to know for certain that at runtime, &lt;STRONG&gt;this object of type B will actually always be of derived type D&lt;/STRONG&gt;. I will inform the compiler of this claim by inserting a cast to D on the expression. Since the compiler probably cannot verify my claim, the compiler might ensure its veracity by inserting a run-time check at the point where I make the claim. If my claim turns out to be inaccurate, the CLR will throw an exception.&lt;BR&gt;
&lt;LI&gt;I have an expression of some type T which &lt;STRONG&gt;I know for certain is not of type U&lt;/STRONG&gt;. However, I have a well-known way of associating some or all values of T with an “equivalent” value of U. I will instruct the compiler to generate code that implements this operation by inserting a cast to U. (And if at runtime there turns out to be no equivalent value of U for the particular T I’ve got, again we throw an exception.)&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The attentive reader will have noticed that these are &lt;EM&gt;opposites&lt;/EM&gt;. A neat trick, to have an operator which means two contradictory things, don’t you think?&lt;/P&gt;
&lt;P&gt;This dichotomy motivates yet another classification scheme for conversions (†).&amp;nbsp; We can divide conversions into &lt;STRONG&gt;representation-preserving conversions&lt;/STRONG&gt; (B to D) and &lt;STRONG&gt;representation-changing conversions&lt;/STRONG&gt; (T to U). (‡) We can think of representation-preserving conversions on reference types as those conversions which &lt;EM&gt;preserve the identity of the object&lt;/EM&gt;. When you cast a B to a D, you’re not doing anything to the existing object; you’re merely &lt;EM&gt;verifying&lt;/EM&gt; that it is actually the type you say it is, and moving on. The identity of the object and&amp;nbsp;the bits which represent the&amp;nbsp;reference&amp;nbsp;stay the same. But when you cast an int to a double, the resulting bits are very different. &lt;/P&gt;
&lt;P&gt;All the built-in reference conversions are identity-preserving (£). Obviously trivial “conversions” such as converting from int to int are also representation-preserving conversions. All user-defined conversions (§) and non-trivial value type conversions (such as converting from int to double) are representation-changing conversions. Boxing and unboxing conversions are all representation-changing conversions.&lt;/P&gt;
&lt;P&gt;The representation-preserving conversions that are known to never fail often result in no codegen at all (₪). If a representation-preserving conversion could fail then a castclass instruction is emitted, which does a runtime check and throws if the check fails. &lt;/P&gt;
&lt;P&gt;But each representation-changing conversion is handled in its own special way. User-defined conversions are resolved using a special version of the overload resolution algorithm, and generated as a call to the appropriate static method. Boxing and unboxing conversions are generated as box and unbox instructions. All the other built-in conversions (int to double, and so on) are generated as &lt;STRONG&gt;custom sequences of instructions&lt;/STRONG&gt; that do the right conversion.&lt;/P&gt;
&lt;P&gt;So now that you know that, consider what the compiler would have to do to make this work the way some people expect:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;int kkk = (int) ooo; &lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;All that the compiler knows is that ooo is of type object. It could be &lt;EM&gt;anything&lt;/EM&gt;. Suppose it is a boxed int – then the compiler should generate an unboxing instruction. Suppose it is a boxed short. Then the compiler should unbox the short and then generate the custom sequence of instructions that convert a short to an&amp;nbsp;int. Suppose it is a boxed double – same thing, but different instructions. And so on, for all the built-in conversions that go to integer.&lt;/P&gt;
&lt;P&gt;This would be a huge amount of code to generate, and it would be very slow. The code is of course so large that you would want to put it in its own method and just generate a call to it. Rather than do that by default, and always generate code that is slow, large and fragile, instead we’ve decided that unboxing can only unbox to the exact type. If you want to call the slow method that does all that goo, it’s available – you can always call Convert.ToInt32, which does all that analysis at runtime for you. We give you the choice between “fast and precise” or “slow and lax”, and &lt;EM&gt;the sensible default is the former&lt;/EM&gt;. If you want the latter then call the method.&lt;/P&gt;
&lt;P&gt;That’s just the built-in conversions. Let’s continue imagining what would have to happen if we wanted &lt;EM&gt;all possible conversions&lt;/EM&gt; to int to just work out correctly at runtime, instead of just bailing out early if the boxed thing is not an int.&lt;/P&gt;
&lt;P&gt;Suppose the object is a Foo where there is a user-defined conversion from Foo (or one of its base classes) to int (or a type implicitly convertible to int, like, say, Nullable&amp;lt;int&amp;gt;). Then the compiler would need to generate a call to that conversion method, just as it would if the type had been known at compile time, and then possibly also generate the conversion from the return type of the method to int.&lt;/P&gt;
&lt;P&gt;Remember, there could be arbitrarily many such conversion methods on arbitrarily many types. The type Foo and its conversion method&amp;nbsp;might not even be defined in the assembly currently&amp;nbsp;being compiled or any assembly referenced. Therefore the compiler would have to generate code to interrogate Foo at runtime, do the overload resolution analysis, and then dynamically spit the code to do the call.&lt;/P&gt;
&lt;P&gt;Which is exactly what the compiler does in C# 4.0 if the argument to the cast is of type “dynamic” instead of object. &lt;EM&gt;The compiler actually generates code which starts a mini version of the compiler up again at runtime, does all that analysis, and spits fresh code&lt;/EM&gt;. This is not &lt;EM&gt;fast&lt;/EM&gt;, but it is &lt;EM&gt;accurate&lt;/EM&gt;, if that’s what you really need. (And the spit code is then cached so that the next time this call site is hit, it is much faster.)&lt;/P&gt;
&lt;P&gt;I don’t think people &lt;EM&gt;really&lt;/EM&gt; expect the compiler to start up again at runtime every time they cast an object to int; I think they just haven’t thought through carefully exactly how much analysis solving the problem would take. Rather a lot, it turns out.&lt;/P&gt;
&lt;P&gt;*************&lt;/P&gt;
&lt;P&gt;(*) Or Nullable&amp;lt;T&amp;gt;.&lt;/P&gt;
&lt;P&gt;(¤) There are others that are not germane to this discussion. For example, a third usage is “Everyone knows that this D is also of base type B; I want the compiler to treat this expression of type D as a B for overload resolution purposes.” That would clearly be an identity-preserving conversion.&lt;/P&gt;
&lt;P&gt;(†) There are many ways to classify conversions; we already divide conversions into implicit/explicit, built-in/user-defined, and so on. For the purposes of this discussion we’ll gloss over the details of those other classifications.&lt;/P&gt;
&lt;P&gt;(‡) I’m glossing over here that certain conversions that the C# compiler thinks of as representation-changing are actually seen by the CLR verifier as representation-preserving. For example, the conversion from int to uint is seen by the CLR as representation-preserving because the 32 bits of a signed integer can be reinterpreted as an unsigned integer without changing the bits. These cases can be subtle and complex, and often have an impact on covariance-related issues; see next footnote.&lt;/P&gt;
&lt;P&gt;I’m also ignoring conversions involving generic type parameters which are not known at compile time to be reference or value types. There are special rules for classifying those which would be major digressions to get into.&lt;/P&gt;
&lt;P&gt;(£) This is why covariant and contravariant conversions of interface and delegate types require that all varying type arguments be of reference types. &lt;STRONG&gt;To ensure that a variant reference conversion is always identity-preserving, all of the conversions involving type arguments must also be identity-preserving.&lt;/STRONG&gt; The easiest way to ensure that all the non-trivial conversions on type arguments are identity-preserving is to restrict them to be reference conversions.&lt;/P&gt;
&lt;P&gt;(§) The rules of C# prohibit all user-defined conversions that could possibly be identity-preserving coercions. More generally, all user-defined conversions that could possibly be any "standard" conversion are illegal.&lt;/P&gt;
&lt;P&gt;(₪) Again, I’m ignoring irksome&amp;nbsp;generic issues here. There are situations where humans can prove mathematically that two generic type parameters must be identical at runtime, but the verifier is not smart enough to make those same deductions and requires the compiler to emit type checks.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9488368" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Performance/default.aspx">Performance</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/Code+Generation/default.aspx">Code Generation</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Conversions/default.aspx">Conversions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx">Covariance and Contravariance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx">Language Design</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/cast+operator/default.aspx">cast operator</category></item><item><title>Chained user-defined explicit conversions in C#, Part Three</title><link>http://blogs.msdn.com/ericlippert/archive/2007/04/20/chained-user-defined-explicit-conversions-in-c-part-three.aspx</link><pubDate>Fri, 20 Apr 2007 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2178829</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/2178829.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=2178829</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Jeroen Frijters knew the answer to my challenge of last time: how is it that &lt;SPAN class=code&gt;Foo foo = new Foo();&lt;/SPAN&gt; can cause a runtime conversion failure? And how is it that &lt;SPAN class=code&gt;Bar bar = (Bar)(new Baz());&lt;/SPAN&gt; can succeed even if there is no user-defined conversion or built-in implicit conversion between &lt;SPAN class=code&gt;Baz&lt;/SPAN&gt; and &lt;SPAN class=code&gt;Bar&lt;/SPAN&gt;?&lt;/P&gt;
&lt;P&gt;The answer is that it is, as Stuart Ballard editorialized, “a goofy COM interop thing that the language should never have supported directly”.&lt;/P&gt;
&lt;P&gt;In COM programming you never talk to a object directly, as a class. Rather, the object has a number of public interfaces; the client of a particular object asks the object for the interface it wants, and it talks to the object on that interface. COM provides a special function called &lt;SPAN class=code&gt;CoCreateInstance&lt;/SPAN&gt; which gets the ball rolling; it knows how to create an instance of a specific class and provides a pointer to a given interface on that object.&lt;/P&gt;
&lt;P&gt;Suppose you need to interoperate with an existing COM object in C#. We could have made you do all the work you’d do in a C++ program: call &lt;SPAN class=code&gt;CoCreateInstance&lt;/SPAN&gt;, get the interface, blah blah blah. But that’s kind of gross and ugly. Instead, we take advantage of the fact that the vast majority of the time that you are talking to a COM object is via an interop library created with the type library importer. The type library importer knows from the information in the type library which interfaces are associated with which coclasses. The typical pattern of interop classes created by the type library importer would look something like this if we wrote out the code in C#:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;using System.Runtime.InteropServices;&lt;BR&gt;[ComImport]&lt;BR&gt;[Guid("12345678-1234-1234-1234-123412341234")]&lt;BR&gt;[CoClass(typeof(InteropClass))]&lt;BR&gt;public interface IMyInterface&lt;BR&gt;{ /* whatever */}&lt;BR&gt;public class InteropClass : IMyInterface {/*whatever*/}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;So the C# compiler knows that &lt;SPAN class=code&gt;IMyInterface&lt;/SPAN&gt; is associated with the coclass &lt;SPAN class=code&gt;InteropClass&lt;/SPAN&gt;. We therefore allow this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;IMyInterface x = new IMyInterface();&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;as is a syntactic sugar for&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;IMyInterface x = (IMyInterface)(new InteropClass());&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;So this is yet another place where we introduce an explicit cast on your behalf. &lt;/P&gt;
&lt;P&gt;This means that it is legal to say&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;InteropClass x = (InteropClass)(new IMyInterface());&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;And it will not fail at run time, even though there is no user-defined conversion or built-in implicit conversion from &lt;SPAN class=code&gt;IMyInterface&lt;/SPAN&gt; to &lt;SPAN class=code&gt;InteropClass&lt;/SPAN&gt;!&lt;/P&gt;
&lt;P&gt;Unfortunately, there’s a bit of a bug in the C# compiler. We assume two things. First, that the type library importer always generates this pattern correctly, and second, that no one other than the type library importer pulls shenanigans like this. The first assumption is probably good, but there’s nothing stopping anyone from pulling shens like:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;using System.Runtime.InteropServices;&lt;BR&gt;[ComImport]&lt;BR&gt;[Guid("12345678-1234-1234-1234-123412341234")]&lt;BR&gt;[CoClass(typeof(InteropClass))]&lt;BR&gt;public interface IMyInterface&lt;BR&gt;{ /* whatever */}&lt;BR&gt;public class InteropClass {/*whatever*/} // oops, no interface&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;The compiler does not check to see if &lt;SPAN class=code&gt;InteropClass&lt;/SPAN&gt; actually implements &lt;SPAN class=code&gt;IMyInterface&lt;/SPAN&gt;! Therefore this guaranteed-to-fail explicit cast gets through at compile time and fails at run time.&lt;/P&gt;
&lt;P&gt;Obviously this is really gross. I don’t think we’ll get to fixing this in C# 3.0, but perhaps in a later version of the language we will tighten this up and make it illegal to have a coclass which does not actually implement the given interface.&lt;/P&gt;
&lt;P&gt;Next time, one more place where poorly specified compiler behaviour causes us to insert an explicit cast.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2178829" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/COM+Programming/default.aspx">COM Programming</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/Puzzles/default.aspx">Puzzles</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Conversions/default.aspx">Conversions</category></item><item><title>Chained user-defined explicit conversions in C#, Part Two</title><link>http://blogs.msdn.com/ericlippert/archive/2007/04/18/chained-user-defined-explicit-conversions-in-c-part-two.aspx</link><pubDate>Wed, 18 Apr 2007 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2155986</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/2155986.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=2155986</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Reader Larry Lard asks a follow-up question regarding &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/04/16/chained-user-defined-explicit-conversions-in-c.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/04/16/chained-user-defined-explicit-conversions-in-c.aspx"&gt;the subject of Monday’s blog entry&lt;/A&gt;. Why is it that the compiler knows that &lt;SPAN class=code&gt;(int)(new Base())&lt;/SPAN&gt; will always fail, and therefore makes the conversion illegal, but does not know that &lt;SPAN class=code&gt;(Derived)(new Base())&lt;/SPAN&gt; will always fail, and make that conversion illegal too? &lt;/P&gt;
&lt;P&gt;There are two answers, a general answer and a specific answer. &lt;/P&gt;
&lt;P&gt;The general answer is that in most cases, the C# type system operates solely on types. There are some exceptions where we peer closer at an expression when doing a conversion – lambdas are the obvious huge exception to that rule, since &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/01/10/lambda-expressions-vs-anonymous-methods-part-one.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/01/10/lambda-expressions-vs-anonymous-methods-part-one.aspx"&gt;the convertibility of a lambda to a particular type depends on the structure of the type and the contents of&amp;nbsp;the lambda parameters and body&lt;/A&gt;. There are smaller exceptions as well – &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2006/03/28/563282.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2006/03/28/563282.aspx"&gt;literal zero is convertible to any enum&lt;/A&gt;, for example. But in general, we cleave to the principle that the type system mostly makes decisions based on the &lt;EM&gt;types&lt;/EM&gt; of expressions, not the &lt;EM&gt;content&lt;/EM&gt; of the expressions themselves. &lt;/P&gt;
&lt;P&gt;Thus, in the examples above, we only see that the argument of the cast operator is something of type &lt;SPAN class=code&gt;Base&lt;/SPAN&gt;. The fact that this thing can be no more derived than &lt;SPAN class=code&gt;Base&lt;/SPAN&gt; is lost; it’s something of type &lt;SPAN class=code&gt;Base&lt;/SPAN&gt;, and therefore might be something that can be converted to &lt;SPAN class=code&gt;Derived&lt;/SPAN&gt;. &lt;/P&gt;
&lt;P&gt;The more specific answer is that &lt;STRONG&gt;in fact, this doesn’t always fail.&lt;/STRONG&gt; Betcha didn’t know that! &lt;/P&gt;
&lt;P&gt;This is one of the most obscure, bizarre (and frankly, also one of the most poorly specified and documented) parts of the C# implementation. I myself just happened to learn about it&amp;nbsp;recently. But it is true -- there is a situation where there is a non-user-defined explicit conversion from &lt;SPAN class=code&gt;Base&lt;/SPAN&gt; to &lt;SPAN class=code&gt;Derived&lt;/SPAN&gt; such that &lt;SPAN class=code&gt;(Derived)(new Base())&lt;/SPAN&gt; succeeds at runtime.&lt;/P&gt;
&lt;P&gt;Via a similar mechanism, there is also a situation where &lt;SPAN class=code&gt;(Base)(new Base())&lt;/SPAN&gt; fails at runtime! &lt;/P&gt;
&lt;P&gt;Actually, it gets even worse than that. Last time, I mentioned that there were two times when the compiler inserts an "explicit" cast on your behalf. The case I am referring to here introduces a third that I didn't know about. This means that it is possible for &lt;SPAN class=code&gt;Base b = new Base();&lt;/SPAN&gt; to compile but fail at runtime!&lt;/P&gt;
&lt;P&gt;So, another challenge to my readers: does anyone know the extremely obscure way that this can happen?&lt;/P&gt;
&lt;P&gt;I’ll give you a hint: the &lt;SPAN class=code&gt;Base&lt;/SPAN&gt; will typically start with the letter &lt;SPAN class=code&gt;I&lt;/SPAN&gt;, not &lt;SPAN class=code&gt;B&lt;/SPAN&gt;...&lt;/P&gt;
&lt;P&gt;And in related news, I've also recently learned of a &lt;EM&gt;fourth&lt;/EM&gt; situation in which the compiler inserts an explicit cast. I'll blog more about that later this week probably.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2155986" 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/Conversions/default.aspx">Conversions</category></item><item><title>Chained user-defined explicit conversions in C#</title><link>http://blogs.msdn.com/ericlippert/archive/2007/04/16/chained-user-defined-explicit-conversions-in-c.aspx</link><pubDate>Mon, 16 Apr 2007 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2102398</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/2102398.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=2102398</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Reader Niall asked me why the following code compiles but produces an exception at runtime:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;class Base {}&lt;BR&gt;class Derived : Base {}&lt;BR&gt;class Castable {&lt;BR&gt;&amp;nbsp;&amp;nbsp;public static explicit operator Base() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return new Base();&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&lt;BR&gt;// ...&lt;BR&gt;Derived d = (Derived)(new Castable());&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;It should be clear why this produces an exception at runtime; the user-defined operator returns a &lt;SPAN class=code&gt;Base&lt;/SPAN&gt; and that is not assignable to a variable of type &lt;SPAN class=code&gt;Derived&lt;/SPAN&gt;. But why does the compiler allow it in the first place?&lt;/P&gt;
&lt;P&gt;First off, let’s define the difference between an implicit and an explicit conversion. An implicit conversion is one which the compiler knows can always be done without incurring the risk of a runtime exception. When you have a method &lt;SPAN class=code&gt;int Foo(int i){...}&lt;/SPAN&gt; and call it with &lt;SPAN class=code&gt;long l = Foo(myshort);&lt;/SPAN&gt;, the compiler inserts implicit conversions from &lt;SPAN class=code&gt;int&lt;/SPAN&gt; to &lt;SPAN class=code&gt;long &lt;/SPAN&gt;on the return side and from &lt;SPAN class=code&gt;short&lt;/SPAN&gt; to &lt;SPAN class=code&gt;int&lt;/SPAN&gt; on the call side. There is no &lt;SPAN class=code&gt;int &lt;/SPAN&gt;which doesn’t fit into a &lt;SPAN class=code&gt;long &lt;/SPAN&gt;and there is no &lt;SPAN class=code&gt;short&lt;/SPAN&gt; which doesn’t fit into an &lt;SPAN class=code&gt;int&lt;/SPAN&gt;, so we know that the conversions will always succeed, so we just up and do them for you.&lt;/P&gt;
&lt;P&gt;There are also conversions which we know at compile time will never succeed. If there is no user-defined conversion from &lt;SPAN class=code&gt;Giraffe&lt;/SPAN&gt; to &lt;SPAN class=code&gt;int&lt;/SPAN&gt;, then &lt;SPAN class=code&gt;Foo(new Giraffe())&lt;/SPAN&gt; is always going to fail at runtime, so this fails at compile time.&lt;/P&gt;
&lt;P&gt;An explicit conversion is a conversion which might succeed sometimes but might also fail. We cannot disallow it, because it might succeed, but we can’t go silently inserting one either, since it might fail unexpectedly. We need to force the developer to acknowledge that risk explicitly. If you called &lt;SPAN class=code&gt;ulong ul = Foo(mynullableint);&lt;/SPAN&gt; then that might fail, so the compiler requires you to spell out that the conversions are explicit. The assignment could be written &lt;SPAN class=code&gt;ulong ul = (ulong)Foo((int)mynullableint);&lt;/SPAN&gt;.&lt;/P&gt;
&lt;P&gt;There are two times that the compiler will insert an explicit cast for you without producing a warning or error. The first is the case above. When a user-defined explicit cast requires an explicit conversion on either the call side or the return side, the compiler will insert the explicit conversions as needed. The compiler figures that if the developer put the explicit cast in the code in the first place then the developer knew what they were doing and took the risk that any of the conversions might fail. That’s what the cast means: this conversion might fail, I will deal with it.&lt;/P&gt;
&lt;P&gt;I understand that this puts a burden upon the developer to fully understand the implications of a cast, but the alternative is to make you spell it out even further, and it just gets to be too much. The logical extreme of this would be a case such as&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;public struct S{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static explicit operator decimal?(S s) {return 1.0m;}&lt;BR&gt;}&lt;BR&gt;//...&lt;BR&gt;S? s = new S();&lt;BR&gt;int i = (int) s;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Here we do first an explicit conversion from &lt;SPAN class=code&gt;S?&lt;/SPAN&gt; to &lt;SPAN class=code&gt;S&lt;/SPAN&gt;, then a user-defined explicit conversion from &lt;SPAN class=code&gt;S&lt;/SPAN&gt; to &lt;SPAN class=code&gt;decimal?&lt;/SPAN&gt;, then an explicit conversion from &lt;SPAN class=code&gt;decimal?&lt;/SPAN&gt; to &lt;SPAN class=code&gt;decimal&lt;/SPAN&gt;, and then an explicit conversion from &lt;SPAN class=code&gt;decimal&lt;/SPAN&gt; to &lt;SPAN class=code&gt;int&lt;/SPAN&gt;. That’s four explicit conversions for the price of one cast, which I think is pretty good value for your money.&lt;/P&gt;
&lt;P&gt;I want to note at this point that this is as long as the chain gets. A user-defined conversion can have built-in conversions inserted automatically on the call and return sides, but we never automatically insert other user-defined conversions. We never say that there’s a user-defined conversion from &lt;SPAN class=code&gt;Alpha&lt;/SPAN&gt; to &lt;SPAN class=code&gt;Bravo&lt;/SPAN&gt;, and a user-defined conversion from &lt;SPAN class=code&gt;Bravo&lt;/SPAN&gt; to &lt;SPAN class=code&gt;Charlie&lt;/SPAN&gt;, and therefore casting an &lt;SPAN class=code&gt;Alpha&lt;/SPAN&gt; to a &lt;SPAN class=code&gt;Charlie&lt;/SPAN&gt; is legal. That doesn’t fly.&lt;/P&gt;
&lt;P&gt;And a built-in conversion can be lifted to nullable, which may introduce additional conversions as in the case above. But again, these are never user-defined.&lt;/P&gt;
&lt;P&gt;The second is in the &lt;SPAN class=code&gt;foreach&lt;/SPAN&gt; loop. If you have &lt;SPAN class=code&gt;foreach(Giraffe g in myAnimals)&lt;/SPAN&gt; then we generate code which fetches each member of the collection and does an “explicit” conversion to &lt;SPAN class=code&gt;Giraffe&lt;/SPAN&gt;. If there happens to be a &lt;SPAN class=code&gt;Snail&lt;/SPAN&gt; or a &lt;SPAN class=code&gt;WaterBuffalo&lt;/SPAN&gt; in &lt;SPAN class=code&gt;myAnimals&lt;/SPAN&gt;, that’s a runtime exception. I considered adding a warning to the compiler for this case to say hey, be aware that your collection is of a more general type, this could fail at runtime. It turns out that there are so many programs which use this programming style, and so many of them have “compile with warnings as errors” turned on in their builds, that this would be a huge breaking change. So we opted to not do it.&lt;/P&gt;&lt;/DIV&gt;&lt;/SPAN&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2102398" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Conversions/default.aspx">Conversions</category></item></channel></rss>