<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2332302504244053100</id><updated>2011-07-08T06:43:04.443+04:00</updated><category term='C# compiler specification implicitly typed local variables var pointers stackalloc'/><category term='C# compiler generics constraints pointers'/><category term='unboxing covariance enums'/><title type='text'>The Labyrinth of C#</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://nikov-thoughts.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332302504244053100/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://nikov-thoughts.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>5</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2332302504244053100.post-1540366288507732758</id><published>2009-08-18T19:53:00.004+04:00</published><updated>2009-08-18T20:01:35.117+04:00</updated><title type='text'>Name resolution in optional parameter initializers</title><content type='html'>&lt;p align=justify&gt;How do you think, what is the meaning of each T in the following C# 4.0 program? Will this code compile?&lt;br /&gt;&lt;div style="overflow: scroll;"&gt;&lt;div style="width: 200%;"&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; A&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public class&lt;/span&gt; T&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;public const int&lt;/span&gt; X = 1;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public void&lt;/span&gt; Foo&amp;lt;T&amp;gt;(&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt; x = T.X, T y = &lt;span style="color: rgb(0, 0, 255);"&gt;default&lt;/span&gt;(T))&lt;br /&gt;    {&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/p&gt;&lt;p align=justify&gt;I will give the explanation in the next post.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332302504244053100-1540366288507732758?l=nikov-thoughts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikov-thoughts.blogspot.com/feeds/1540366288507732758/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332302504244053100&amp;postID=1540366288507732758' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332302504244053100/posts/default/1540366288507732758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332302504244053100/posts/default/1540366288507732758'/><link rel='alternate' type='text/html' href='http://nikov-thoughts.blogspot.com/2009/08/name-resolution-in-optional-parameter.html' title='Name resolution in optional parameter initializers'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332302504244053100.post-6146521742249388852</id><published>2008-06-09T22:06:00.005+04:00</published><updated>2009-10-19T19:54:19.552+04:00</updated><title type='text'>An Implicit Conversion Can Exist, But Still Fail At Compile-Time</title><content type='html'>&lt;p align=justify&gt;One important thing to know about implicit conversions in C#: they can exist but still fail at compile-time. Yes, I mean a very compile-time error, not a runtime exception. It can lead to subtle surprises in overload resolution. Let us look at examples:&lt;/p&gt;&lt;p&gt;1)&lt;/p&gt;&lt;div style="overflow: scroll;"&gt;&lt;div style="width: 200%;"&gt;&lt;pre&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; A&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; Main()&lt;br /&gt;    {&lt;br /&gt;        B b = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; B();&lt;br /&gt;        Foo(b);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; Foo(A x) { }&lt;br /&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; Foo(IB x) { }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;implicit&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;operator&lt;/span&gt; A(B x)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;erface&lt;/span&gt; IB {}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; B : IB&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;implicit&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;operator&lt;/span&gt; A(B x)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p align=justify&gt;The compilation of this program leads to the following compile-time error:&lt;/p&gt;&lt;pre&gt;error CS0121: The call is ambiguous between the following&lt;br /&gt;methods or properties: 'A.Foo(A)' and 'A.Foo(IB)'&lt;/pre&gt;&lt;p align=justify&gt;The second overload Foo(IB) is obviously applicable, because there is an implicit conversion from the class B to the interface IB, which it implements. Indeed, if you comment out the first overload Foo(A), the compilation succeeds. But what will happen, if you comment out the second overload and leave Foo(A)? You will get an ambiguity in the conversion from B to A, because the compiler will find two user-defined conversion operators from B to A. Interesting part begins here! Does an implicit conversion from B to A exist? Is the method Foo(A) applicable?&lt;/p&gt;&lt;p align=justify&gt;The right answer is 'Yes'. The implicit conversion exist, but it is ambiguous and fails at compile-time. Nevertheless, the method Foo(A) is applicable. So, if you have both overloads, the invocation of Foo becomes ambiguous.&lt;/p&gt;&lt;small align=justify&gt;Note: If you have ReSharper installed, you might notice that its error analysis shows no errors in this code. So, it does not know about this subtlety. I has already logged a bug for this.&lt;/small&gt;&lt;p&gt;2)&lt;/p&gt;&lt;div style="overflow: scroll;"&gt;&lt;div style="width: 200%;"&gt;&lt;pre&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; A&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; Main()&lt;br /&gt;    {&lt;br /&gt;        Bar(Foo);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; Foo(&lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; x) { }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; Bar(Action&lt;&lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;&gt; x){}&lt;br /&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; Bar(Action&lt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&gt; x){}&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p align=justify&gt;The compilation of this program leads to the following compile-time error:&lt;/p&gt;&lt;pre&gt;error CS0121: The call is ambiguous between the following&lt;br /&gt;methods or properties: 'A.Bar(System.Action&amp;lt;object&gt;)'&lt;br /&gt;and 'A.Bar(System.Action&amp;lt;int&gt;)'&lt;/pre&gt;&lt;p align=justify&gt;Again, the first overload Bar(Action&amp;lt;object&gt;) is obviously applicable. If you comment out it and leave only Bar(Action&amp;lt;int&gt;), you will get the following error:&lt;/p&gt;&lt;pre&gt;error CS0123: No overload for 'A.Foo(object)'&lt;br /&gt;matches delegate 'System.Action&amp;lt;int&gt;'&lt;/pre&gt;&lt;p align=justify&gt;This is correct, because a contravariance in parameter types works only for reference types. So, does an implicit conversion from the method group Foo to Action&amp;lt;int&gt; exist? Again, we are tempted to answer 'No', but the correct answer is 'Yes. Exists, but fails an compile-time'. So, the overload Bar(Action&amp;lt;int&gt; x) is applicable, and we have an ambiguity.&lt;/p&gt;&lt;small align=justify&gt;Note: Again, ReSharper is wrong here.&lt;/small&gt;&lt;p align=justify&gt;There are many reasons, why an existing implicit conversion from a method group to a delegate type may fail at compile-time:&lt;ul&gt;&lt;li&gt;Overload resolution cannot pick the best method from the method group being converted.&lt;br /&gt;&lt;li&gt;The best method is generic, and constraints on its type parameters are not satisfied.&lt;br /&gt;&lt;li&gt;The best method has a wrong return type.&lt;br /&gt;&lt;li&gt;For at least one parameter, the conversion from the type of the parameter of the delegate to the type of the parameter of the best method is not an identity or an implicit reference conversion.&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;3)&lt;/p&gt;&lt;div style="overflow: scroll;"&gt;&lt;div style="width: 200%;"&gt;&lt;pre&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.Linq.Expressions;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; A&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; Main()&lt;br /&gt;    {&lt;br /&gt;        Bar(x =&gt; { &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; x; });&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; Bar(Func&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;,&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&gt; x) { }&lt;br /&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; Bar(Expression&amp;lt;Func&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;, &lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&gt;&gt; x) { }&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p align=justify&gt;A lambda-expression with a statement body cannot be converted to an expression tree type, but the conversion still exists, since there is a conversion to the corresponding delegate type. The invocation of Bar is ambiguous.&lt;/p&gt;&lt;small align=justify&gt;Note: ReSharper is correct here.&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332302504244053100-6146521742249388852?l=nikov-thoughts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikov-thoughts.blogspot.com/feeds/6146521742249388852/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332302504244053100&amp;postID=6146521742249388852' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332302504244053100/posts/default/6146521742249388852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332302504244053100/posts/default/6146521742249388852'/><link rel='alternate' type='text/html' href='http://nikov-thoughts.blogspot.com/2008/06/implicit-conversion-can-exist-but-still.html' title='An Implicit Conversion Can Exist, But Still Fail At Compile-Time'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332302504244053100.post-8113208574124155824</id><published>2008-03-11T08:09:00.004+03:00</published><updated>2008-03-11T09:01:37.279+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unboxing covariance enums'/><title type='text'>The Surprising Unboxing</title><content type='html'>&lt;p align=justify&gt;The unboxing to a non-nullable value type seems to be a simple thing, doesn't it? Check whether the object instance is a boxed value of the given value type. If yes, copy the value out of the instance. If no, throw System.NullReferenceException if the object instance is null, or throw System.InvalidCastException otherwise. That is what The C# Specification says. Simply? Not exactly.&lt;/p&gt;&lt;br /&gt;&lt;p align=justify&gt;Yesterday I noticed that the actual behavior differs from the specified. Compile and run the following code:&lt;/p&gt;&lt;div style="overflow: scroll;"&gt;&lt;div style="width: 200%;"&gt;&lt;pre class="hl"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;enum&lt;/span&gt; E { }&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; &lt;span class="hl kwd"&gt;Main&lt;/span&gt;&lt;span class="hl sym"&gt;()&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(0, 128, 0);"&gt;// box a value of type E&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; x = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; E();&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: rgb(0, 128, 0);"&gt;// unbox the result to System.Int32&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt; y = (&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;) x;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: rgb(0, 128, 0);"&gt;// the unboxing succeeded, 0 is printed out&lt;/span&gt;&lt;br /&gt;        Console.WriteLine(y);&lt;br /&gt;    &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p align=justify&gt;We boxed the value of type E, and successfully unboxed it to a different type, System.Int32. What about arrays of these types? Are they covariant (God forbid)?&lt;/p&gt;&lt;div style="overflow: scroll;"&gt;&lt;div style="width: 200%;"&gt;&lt;pre class="hl"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;enum&lt;/span&gt; E { }&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; &lt;span class="hl kwd"&gt;Main&lt;/span&gt;&lt;span class="hl sym"&gt;()&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; x = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; E[] { &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; E() };&lt;br /&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;[] y = (&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;[]) x;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: rgb(0, 128, 0);"&gt;// the conversion succeeded, 0 is printed out&lt;/span&gt;&lt;br /&gt;        Console.WriteLine(y[0]);&lt;br /&gt;    &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p align=justify&gt;From The C# Specification's point of view, it is a nonsense. Only arrays of reference type can be covariant. "Ah," one can say, "the underlying type of E is int. The trick should be here!" No.&lt;/p&gt;&lt;div style="overflow: scroll;"&gt;&lt;div style="width: 200%;"&gt;&lt;pre class="hl"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;enum&lt;/span&gt; E { }&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; &lt;span class="hl kwd"&gt;Main&lt;/span&gt;&lt;span class="hl sym"&gt;()&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; x = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; E[] { &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; E() };&lt;br /&gt;        IntPtr[] y = (IntPtr[]) x;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: rgb(0, 128, 0);"&gt;// the conversion succeeded, 0 is printed out&lt;/span&gt;&lt;br /&gt;        Console.WriteLine(y[0]);&lt;br /&gt;    &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p align=justify&gt;The type System.IntPtr has nothing to do with E (only their sizes match), but the conversion still succeeds.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332302504244053100-8113208574124155824?l=nikov-thoughts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikov-thoughts.blogspot.com/feeds/8113208574124155824/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332302504244053100&amp;postID=8113208574124155824' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332302504244053100/posts/default/8113208574124155824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332302504244053100/posts/default/8113208574124155824'/><link rel='alternate' type='text/html' href='http://nikov-thoughts.blogspot.com/2008/03/surprising-unboxing.html' title='The Surprising Unboxing'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332302504244053100.post-1780407229981397195</id><published>2008-02-03T18:01:00.000+03:00</published><updated>2008-02-04T13:18:34.247+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C# compiler specification implicitly typed local variables var pointers stackalloc'/><title type='text'>Implicitly Typed Local Variables And A Stackalloc Initializer</title><content type='html'>&lt;p align="justify"&gt;The C# 3.0 contains a great new feature: implicitly typed local variables. This feature is described in The C# 3.0 Specification, 8.5.1 Local variable declarations. That paragraph includes the following rule:&lt;/p&gt;&lt;div style="border:1px solid #c0c0c0;padding-left:5px;padding-right:5px;"&gt;&lt;p align="justify"&gt;Implicitly typed local variable declarations are subject to the following restrictions:&lt;br&gt;.......&lt;br&gt;&lt;ul&gt;&lt;li&gt;The &lt;i&gt;local-variable-initializer&lt;/i&gt; must be an &lt;i&gt;expression&lt;/i&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;/div&gt;&lt;p align="justify"&gt;What does it mean? Generally, a &lt;i&gt;local-variable-initializer&lt;/i&gt; can be of the following forms: an &lt;i&gt;expression&lt;/i&gt;, an &lt;i&gt;array-initializer&lt;/i&gt; and a &lt;i&gt;stackalloc-initializer&lt;/i&gt;. An &lt;i&gt;array-initializer&lt;/i&gt; can be used to initialize a variable of an array type in a concise form. A &lt;i&gt;stackalloc-initializer&lt;/i&gt; can be used in an unsafe context to perform a stack allocation and initialize a variable of a pointer type with a pointer to the newly allocated memory block. Neither an &lt;i&gt;array-initializer&lt;/i&gt; nor a &lt;i&gt;stackalloc-initializer&lt;/i&gt; is an expression (if you try to use them as expressions, you will get a bunch of errors during the syntactic analysis). So, it looks like it is not possible to use an &lt;i&gt;array-initializer&lt;/i&gt; or a &lt;i&gt;stackalloc-initializer&lt;/i&gt; as an initializer of an implicitly typed local variable. Let us check it:&lt;/p&gt;&lt;div style="overflow: scroll;"&gt;&lt;div style="width: 200%;"&gt;&lt;pre class="hl"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;// Do not forget to use the /unsafe option&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;// when compiling this code&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;unsafe static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; &lt;span class="hl kwd"&gt;Main&lt;/span&gt;&lt;span class="hl sym"&gt;()&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(0, 128, 0);"&gt;// error CS0820: Cannot initialize an implicitly-typed&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(0, 128, 0);"&gt;// local variable with an array initializer&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; x = { 1, 2, 3 };&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: rgb(0, 128, 0);"&gt;// No error here!&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; p &lt;span class="hl sym"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;stackalloc&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&lt;span class="hl sym"&gt;[&lt;/span&gt;1&lt;span class="hl sym"&gt;];&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p align="justify"&gt;It turns out, that the compiler accepts a &lt;i&gt;stackalloc-initializer&lt;/i&gt; as an initializer of an implicitly typed local variable! I hope, The Specification will be fixed soon to reflect this.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332302504244053100-1780407229981397195?l=nikov-thoughts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikov-thoughts.blogspot.com/feeds/1780407229981397195/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332302504244053100&amp;postID=1780407229981397195' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332302504244053100/posts/default/1780407229981397195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332302504244053100/posts/default/1780407229981397195'/><link rel='alternate' type='text/html' href='http://nikov-thoughts.blogspot.com/2008/02/implicitly-typed-local-variables-and.html' title='Implicitly Typed Local Variables And A Stackalloc Initializer'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2332302504244053100.post-6839792752389442497</id><published>2008-02-03T12:11:00.001+03:00</published><updated>2008-02-03T17:43:53.319+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C# compiler generics constraints pointers'/><title type='text'>Sometimes The C# Compiler Does Not Validate Supplied Type Arguments</title><content type='html'>&lt;p align="justify"&gt;Recently I noticed that sometimes the C# compiler does not validate type arguments supplied in a constructed type, if the constructed type itself occurs within a constraint of a type parameter. Consider the following code:&lt;/p&gt;&lt;div style="overflow: scroll;"&gt;&lt;div style="width: 200%;"&gt;&lt;pre class="hl"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; A&lt;br /&gt;&lt;span&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 255);"&gt;public interface&lt;/span&gt; I &lt;span&gt;{ }&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; C&lt;span&gt;&amp;lt;&lt;/span&gt;T&lt;span&gt;&amp;gt; :&lt;/span&gt; A &lt;span style="color: rgb(0, 0, 255);"&gt;where&lt;/span&gt; T &lt;span&gt;:&lt;/span&gt; C&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&lt;span&gt;&amp;gt;.&lt;/span&gt;I&lt;br /&gt;&lt;span&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p align="justify"&gt;Obviously, the type argument &lt;b&gt;int&lt;/b&gt; does not satisfy the corresponding constraint, but the compiler does not issue an error here. In fact, you are allowed to supply an absolute garbage in this context:&lt;/p&gt;&lt;div style="overflow: scroll;"&gt;&lt;div style="width: 200%;"&gt;&lt;pre class="hl"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; A&lt;br /&gt;&lt;span&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 255);"&gt;public interface&lt;/span&gt; I &lt;span&gt;{ }&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; C&lt;span&gt;&amp;lt;&lt;/span&gt;T&lt;span&gt;&amp;gt; :&lt;/span&gt; A &lt;span style="color: rgb(0, 0, 255);"&gt;where&lt;/span&gt; T &lt;span&gt;:&lt;/span&gt; C&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;*&lt;span&gt;&amp;gt;.&lt;/span&gt;I&lt;br /&gt;&lt;span&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p align="justify"&gt;Note that generally it is not legal to declare a pointer to a managed type (&lt;b&gt;object&lt;/b&gt;), to use pointers in a safe context or to supply a pointer as a type argument. But in this case, the compiler does not enforce these rules. Why?&lt;/p&gt;&lt;p align="justify"&gt;The point is that the C# language allows to refer to a nested type, declared in a non-generic class, both through its declaring class and through a class, derived from the declaring class (but it is not possible to capture this difference in the IL or metadata). If the derived class is a constructed generic class, then type arguments supplied for that class are actually discarded. It leads to an interesting conclusion that even if a &lt;i&gt;type-name&lt;/i&gt; involves type arguments, it still may denote a non-generic type.&lt;/p&gt;&lt;p align="justify"&gt;So, in the previous examples the constraint is actually interpreted in the following way:&lt;/p&gt;&lt;div style="overflow: scroll;"&gt;&lt;div style="width: 200%;"&gt;&lt;pre class="hl"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; A&lt;br /&gt;&lt;span&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 255);"&gt;public interface&lt;/span&gt; I &lt;span&gt;{ }&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; C&lt;span&gt;&amp;lt;&lt;/span&gt;T&lt;span&gt;&amp;gt; :&lt;/span&gt; A &lt;span style="color: rgb(0, 0, 255);"&gt;where&lt;/span&gt; T &lt;span&gt;:&lt;/span&gt; A.I&lt;br /&gt;&lt;span&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p align="justify"&gt;Thus, no invalid types get into the compiled assembly, and it is great! But the behavior of the compiler still looks inconsistent. Note that if the same fake generic type (C&amp;lt;&lt;B&gt;int&lt;/B&gt;&amp;gt;.I) occurs within the body of a method, a compile-time error is issued:&lt;/p&gt;&lt;div style="overflow: scroll;"&gt;&lt;div style="width: 200%;"&gt;&lt;pre class="hl"&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt; A&lt;br /&gt;&lt;span&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000FF;"&gt;public interface&lt;/span&gt; I &lt;span&gt;{ }&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000FF;"&gt;class&lt;/span&gt; C&lt;span&gt;&amp;lt;&lt;/span&gt;T&lt;span&gt;&amp;gt; :&lt;/span&gt; A &lt;span style="color: rgb(0, 0, 255);"&gt;where&lt;/span&gt; T &lt;span&gt;:&lt;/span&gt; C&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span&gt;&amp;gt;.&lt;/span&gt;I&lt;br /&gt;&lt;span&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000FF;"&gt;static&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;void&lt;/span&gt; &lt;span class="hl kwd"&gt;Foo&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;br /&gt;    &lt;span&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#008000;"&gt;// error CS0315: The type 'int' cannot be used as&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#008000;"&gt;// type parameter 'T' in the generic type or method 'C&amp;lt;T&amp;gt;'.&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#008000;"&gt;// There is no boxing conversion from 'int' to 'A.I'.&lt;/span&gt;&lt;br /&gt;        C&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span&gt;&amp;gt;.&lt;/span&gt;I x&lt;span&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2332302504244053100-6839792752389442497?l=nikov-thoughts.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikov-thoughts.blogspot.com/feeds/6839792752389442497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2332302504244053100&amp;postID=6839792752389442497' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2332302504244053100/posts/default/6839792752389442497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2332302504244053100/posts/default/6839792752389442497'/><link rel='alternate' type='text/html' href='http://nikov-thoughts.blogspot.com/2008/02/sometimes-c-compiler-does-not-validate.html' title='Sometimes The C# Compiler Does Not Validate Supplied Type Arguments'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>3</thr:total></entry></feed>
