<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" media="screen" href="/App_Themes/default/rss.xslt"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:evnet="http://www.mscommunities.com/rssmodule/"><channel><title>Comment Feed for Why doesn't the C# compiler turn "" into string.Empty? (TechOff on Channel 9)</title><atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/forums/techoff/450791-why-doesnt-the-c-compiler-turn--into-stringempty/rss/default.aspx" /><image><url>http://mschnlnine.vo.llnwd.net/d1/Dev/App_Themes/C9/images/feedimage.png</url><title>Comment Feed for Why doesn't the C# compiler turn "" into string.Empty? (TechOff on Channel 9)</title><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/</link></image><description>Why doesn't the C# compiler turn "" into string.Empty?</description><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/</link><language>en-us</language><pubDate>Thu, 08 Jan 2009 11:10:33 GMT</pubDate><lastBuildDate>Thu, 08 Jan 2009 11:10:33 GMT</lastBuildDate><generator>EvNet (EvNet, Version=1.0.3608.3122, Culture=neutral, PublicKeyToken=null)</generator><item><title>Re: Re: Re: Re: Re: Re: Re: Re: Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>It makes no difference. Even on an x64 it's faster to do compare 32bits at a time because the processor can automatically redirect 32bit check loops through SSE and SSE2 instructions which are substantially faster.&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;@CannotResolveSymbol: It's handwritten, but it's been handwritten by someone who knows what they're doing.&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;The first check gets rid of the easy cases (length difference) and the method assumes that the arguments are non-null. It then has to fix both strings to get a char* for them and then search through them. It then notices rather cleverly that processors will stream the instructions, so it blocks them in 10 comparisons at once in the first loop (avoiding IP jumps which breaks streaming) and then goes through the remaining elements one by one in the second while loop.&lt;/div&gt;</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451885</link><pubDate>Thu, 08 Jan 2009 11:10:33 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451885</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451885/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>It makes no difference. Even on an x64 it's faster to do compare 32bits at a time because the processor can automatically redirect 32bit check loops through SSE and SSE2 instructions which are substantially faster.@CannotResolveSymbol: It's handwritten, but it's been handwritten by someone who knows&amp;#8230;</evnet:previewtext><dc:creator>evildictaitor</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451885/Trackback.aspx</trackback:ping></item><item><title>Re: Re: Re: Re: Re: Re: Re: Re: Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>You can see the original source in SSCLI, it's the same. Even without the source you can conclude that it was written by a human, the C# compiler doesn't perform such kind of optimizations.&lt;BR&gt;</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451865</link><pubDate>Thu, 08 Jan 2009 08:29:31 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451865</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451865/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>You can see the original source in SSCLI, it's the same. Even without the source you can conclude that it was written by a human, the C# compiler doesn't perform such kind of optimizations.</evnet:previewtext><dc:creator>Dexter</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451865/Trackback.aspx</trackback:ping></item><item><title>Re: Re: Re: Re: Re: Re: Re: Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>Because 32-bit systems natively do integer operations with 32-bit integers, perhaps?  What do you get if you compile as 64-bit (or look at the 64-bit version of the runtime)?&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;I'd also be interested in seeing the actual (original, non-compiled) source to EqualsHelper()...  was that code entirely written by a human or is the compiler doing some degree of loop unrolling there?&lt;/div&gt;</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451805</link><pubDate>Thu, 08 Jan 2009 01:46:49 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451805</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451805/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Because 32-bit systems natively do integer operations with 32-bit integers, perhaps?  What do you get if you compile as 64-bit (or look at the 64-bit version of the runtime)?I'd also be interested in seeing the actual (original, non-compiled) source to EqualsHelper()...  was that code entirely&amp;#8230;</evnet:previewtext><dc:creator>JonathonW</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451805/Trackback.aspx</trackback:ping></item><item><title>Re: Re: Re: Re: Re: Re: Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>I wonder why they didn't use longs... compare 8 bytes instead&lt;br&gt;</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451801</link><pubDate>Thu, 08 Jan 2009 00:55:44 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451801</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451801/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>I wonder why they didn't use longs... compare 8 bytes instead</evnet:previewtext><dc:creator>Minh</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451801/Trackback.aspx</trackback:ping></item><item><title>Re: Re: Re: Re: Re: Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>Except that Duff's device can't be used in C# (no fall through on cases).</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451777</link><pubDate>Wed, 07 Jan 2009 21:37:50 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451777</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451777/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Except that Duff's device can't be used in C# (no fall through on cases).</evnet:previewtext><dc:creator>AndyC</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451777/Trackback.aspx</trackback:ping></item><item><title>Re: Re: Re: Re: Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>&amp;gt; Comparison loop&lt;br&gt;&lt;br&gt;Looks like a candidate for &lt;a href="http://en.wikipedia.org/wiki/Duff%27s_device"&gt;Duff's device&lt;/a&gt;.&lt;br&gt;</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451759</link><pubDate>Wed, 07 Jan 2009 20:46:50 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451759</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451759/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>&amp;gt; Comparison loopLooks like a candidate for Duff's device.</evnet:previewtext><dc:creator>Matthew van Eerde</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451759/Trackback.aspx</trackback:ping></item><item><title>Re: Re: Re: Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>Comparison loop re-written... interesting... 2 chars (4 bytes) are compared at a time... pointer arithmetics... oh my...&lt;br&gt;&lt;br&gt;int lenA = strA.Length&lt;br&gt;&lt;br&gt;if (lenA != strB.Length) return false;&lt;br&gt;&lt;br&gt;char* pA = (char*) strA;&amp;nbsp; // a .Net "char" is 2 bytes&lt;br&gt;char* pB = (char*) strB;&lt;br&gt;&lt;br&gt;while (lenA &amp;gt;= 10)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp; int iA1 = *((int *) pA);&lt;br&gt;&amp;nbsp;&amp;nbsp; int iB1 = *((int *) pB);&lt;br&gt;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp; int iA2 = *((int *) (pA + 2));&amp;nbsp;&amp;nbsp; // a .Net "int" is 2 chars (4 bytes)&lt;br&gt;&amp;nbsp;&amp;nbsp; int iB2 = *((int *) (pB + 2));&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; int iA3 = *((int *) (pA + 4));&lt;br&gt;&amp;nbsp;&amp;nbsp; int iB3 = *((int *) (pB + 4));&lt;br&gt;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp; int iA4 = *((int *) (pA + 6));&lt;br&gt;&amp;nbsp;&amp;nbsp; int iB4 = *((int *) (pB + 6));&lt;br&gt;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp; int iA5 = *((int *) (pA + 8));&lt;br&gt;&amp;nbsp;&amp;nbsp; int iB5 = *((int *) (pB + 8));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp; if (iA1 != iB1 || iA2 != iB2 || iA3 != iB3 || iA4 != iB4 || iA5 != iB5)&lt;br&gt;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br&gt;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp; pA += 10;&lt;br&gt;&amp;nbsp;&amp;nbsp; pB += 10;&lt;br&gt;&amp;nbsp;&amp;nbsp; lenA -= 10;&lt;br&gt;}&lt;br&gt;&lt;br&gt;while (lenA &amp;gt; 0)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp; int iA1 = *((int *) pA);&lt;br&gt;&amp;nbsp;&amp;nbsp; int iB1 = *((int *) pB);&lt;br&gt;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp; if (iA1 != iB1)&lt;br&gt;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br&gt;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp; pA += 2;&lt;br&gt;&amp;nbsp;&amp;nbsp; pB += 2;&lt;br&gt;&amp;nbsp;&amp;nbsp; lenA -= 2;&lt;br&gt;}&lt;br&gt;&lt;br&gt;return (lenA &amp;lt;= 0);</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451752</link><pubDate>Wed, 07 Jan 2009 20:22:35 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451752</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451752/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Comparison loop re-written... interesting... 2 chars (4 bytes) are compared at a time... pointer arithmetics... oh my...int lenA = strA.Lengthif (lenA != strB.Length) return false;char* pA = (char*) strA;&amp;nbsp; // a .Net "char" is 2 byteschar* pB = (char*) strB;while (lenA &amp;gt;= 10){&amp;nbsp;&amp;nbsp; int&amp;#8230;</evnet:previewtext><dc:creator>Minh</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451752/Trackback.aspx</trackback:ping></item><item><title>Re: Re: Re: Re: Re: Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>&amp;gt; Personally, I always just use "". I find it easier to read...&lt;br&gt;&lt;br&gt;Hear, hear!&amp;nbsp; Code has three consumers: the compiler, the developer (me) and the person who gets to maintain it later (probably me again after a couple of weeks of not looking at the code.)&lt;br&gt;&lt;br&gt;Making code easy to read is good for two of these consumers.&amp;nbsp; Performance optimization at the cost of readability had better be mission-critical.&lt;br&gt;</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451713</link><pubDate>Wed, 07 Jan 2009 16:57:12 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451713</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451713/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>&amp;gt; Personally, I always just use "". I find it easier to read...Hear, hear!&amp;nbsp; Code has three consumers: the compiler, the developer (me) and the person who gets to maintain it later (probably me again after a couple of weeks of not looking at the code.)Making code easy to read is good for two&amp;#8230;</evnet:previewtext><dc:creator>Matthew van Eerde</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451713/Trackback.aspx</trackback:ping></item><item><title>Re: Re: Re: Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>The "master table" actually exists and it's called "intern pool" but it is not used automatically. You have to explicitly use String.Intern for a string to be stored in that table.&lt;BR&gt;&lt;BR&gt;It appears that string literals are automatically interned (I get true for Object.ReferenceEquals(String.Empty, "")) but some said earlier in the thread that they get false so I'm not sure if it happens always. Maybe different runtime versions behave differently.&lt;BR&gt;&lt;BR&gt;Funny that if string literals are indeed automatically interned then it's almost as if the C# compiler replaced "" with String.Empty :).&lt;BR&gt;</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451270</link><pubDate>Mon, 05 Jan 2009 01:14:24 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451270</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451270/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>The "master table" actually exists and it's called "intern pool" but it is not used automatically. You have to explicitly use String.Intern for a string to be stored in that table.It appears that string literals are automatically interned (I get true for Object.ReferenceEquals(String.Empty, "")) but&amp;#8230;</evnet:previewtext><dc:creator>Dexter</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451270/Trackback.aspx</trackback:ping></item><item><title>Re: Re: Re: Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>Damn! Somebody want to work on that unrolled loop?&lt;br&gt;</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451257</link><pubDate>Sun, 04 Jan 2009 23:32:10 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451257</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451257/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Damn! Somebody want to work on that unrolled loop?</evnet:previewtext><dc:creator>Minh</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451257/Trackback.aspx</trackback:ping></item><item><title>Re: Re: Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>Woweewow, did I ever get it wrong... I never thought that string comparison would be done via char-to-char comparison, but Reflector shows all... What the eff was that master string table I read about? Oh, well, here's what Reflector has to say about string comparison:&lt;br&gt;&lt;br&gt;&lt;table cellpadding="0" cellspacing="0"&gt;

&lt;tr&gt;
&lt;td colspan="2"&gt;&lt;pre&gt;public static &lt;a title="System.Boolean" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Boolean"&gt;bool&lt;/a&gt; &lt;b&gt;&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.String/Equals%28String,String%29:Boolean"&gt;Equals&lt;/a&gt;&lt;/b&gt;(&lt;a title="System.String" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.String"&gt;string&lt;/a&gt; a, &lt;a title="System.String" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.String"&gt;string&lt;/a&gt; b)
{
    return ((&lt;a title="string a; // Parameter"&gt;a&lt;/a&gt; == &lt;a title="string b; // Parameter"&gt;b&lt;/a&gt;) || (((&lt;a title="string a; // Parameter"&gt;a&lt;/a&gt; != null) &amp;amp;&amp;amp; (&lt;a title="string b; // Parameter"&gt;b&lt;/a&gt; != null)) &amp;amp;&amp;amp; &lt;a title="bool System.String.EqualsHelper(string strA, string strB);" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.String/EqualsHelper%28String,String%29:Boolean"&gt;EqualsHelper&lt;/a&gt;(&lt;a title="string a; // Parameter"&gt;a&lt;/a&gt;, &lt;a title="string b; // Parameter"&gt;b&lt;/a&gt;)));
}
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;table cellpadding="0" cellspacing="0"&gt;

&lt;tr&gt;
&lt;td colspan="2"&gt;&lt;pre&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br&gt;&lt;pre&gt;[&lt;a title="System.Runtime.ConstrainedExecution.ReliabilityContractAttribute.ReliabilityContractAttribute(Consistency consistencyGuarantee, Cer cer);" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Runtime.ConstrainedExecution.ReliabilityContractAttribute/.ctor%28System.Runtime.ConstrainedExecution.Consistency,System.Runtime.ConstrainedExecution.Cer%29"&gt;ReliabilityContract&lt;/a&gt;(&lt;a title="System.Runtime.ConstrainedExecution.Consistency" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Runtime.ConstrainedExecution.Consistency"&gt;Consistency&lt;/a&gt;.&lt;a title="Consistency System.Runtime.ConstrainedExecution.Consistency.WillNotCorruptState;" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Runtime.ConstrainedExecution.Consistency/WillNotCorruptState"&gt;WillNotCorruptState&lt;/a&gt;, &lt;a title="System.Runtime.ConstrainedExecution.Cer" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Runtime.ConstrainedExecution.Cer"&gt;Cer&lt;/a&gt;.&lt;a title="Cer System.Runtime.ConstrainedExecution.Cer.MayFail;" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Runtime.ConstrainedExecution.Cer/MayFail"&gt;MayFail&lt;/a&gt;)]&lt;br&gt;private static unsafe &lt;a title="System.Boolean" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Boolean"&gt;bool&lt;/a&gt; &lt;b&gt;&lt;a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.String/EqualsHelper%28String,String%29:Boolean"&gt;EqualsHelper&lt;/a&gt;&lt;/b&gt;(&lt;a title="System.String" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.String"&gt;string&lt;/a&gt; strA, &lt;a title="System.String" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.String"&gt;string&lt;/a&gt; strB)&lt;br&gt;{&lt;br&gt;    &lt;a title="System.Int32" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Int32"&gt;int&lt;/a&gt; &lt;b&gt;length&lt;/b&gt; = &lt;a title="string strA; // Parameter"&gt;strA&lt;/a&gt;.&lt;a title="int System.String.Length { ... }" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.String/property:Length:Int32"&gt;Length&lt;/a&gt;;&lt;br&gt;    if (&lt;a title="int length // Local Variable"&gt;length&lt;/a&gt; != &lt;a title="string strB; // Parameter"&gt;strB&lt;/a&gt;.&lt;a title="int System.String.Length { ... }" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.String/property:Length:Int32"&gt;Length&lt;/a&gt;)&lt;br&gt;    {&lt;br&gt;        return false;&lt;br&gt;    }&lt;br&gt;    fixed (&lt;a title="System.Char" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Char"&gt;char&lt;/a&gt;* &lt;b&gt;str&lt;/b&gt; = ((&lt;a title="System.Char" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Char"&gt;char&lt;/a&gt;*) &lt;a title="string strA; // Parameter"&gt;strA&lt;/a&gt;))&lt;br&gt;    {&lt;br&gt;        &lt;a title="System.Char" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Char"&gt;char&lt;/a&gt;* &lt;b&gt;chPtr&lt;/b&gt; = &lt;a title="char* str // Local Variable"&gt;str&lt;/a&gt;;&lt;br&gt;        fixed (&lt;a title="System.Char" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Char"&gt;char&lt;/a&gt;* &lt;b&gt;str2&lt;/b&gt; = ((&lt;a title="System.Char" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Char"&gt;char&lt;/a&gt;*) &lt;a title="string strB; // Parameter"&gt;strB&lt;/a&gt;))&lt;br&gt;        {&lt;br&gt;            &lt;a title="System.Char" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Char"&gt;char&lt;/a&gt;* &lt;b&gt;chPtr2&lt;/b&gt; = &lt;a title="char* str2 // Local Variable"&gt;str2&lt;/a&gt;;&lt;br&gt;            &lt;a title="System.Char" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Char"&gt;char&lt;/a&gt;* &lt;b&gt;chPtr3&lt;/b&gt; = &lt;a title="char* chPtr // Local Variable"&gt;chPtr&lt;/a&gt;;&lt;br&gt;            &lt;a title="System.Char" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Char"&gt;char&lt;/a&gt;* &lt;b&gt;chPtr4&lt;/b&gt; = &lt;a title="char* chPtr2 // Local Variable"&gt;chPtr2&lt;/a&gt;;&lt;br&gt;            while (&lt;a title="int length // Local Variable"&gt;length&lt;/a&gt; &amp;gt;= 10)&lt;br&gt;            {&lt;br&gt;                if ((((*(((&lt;a title="System.Int32" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Int32"&gt;int&lt;/a&gt;*) &lt;a title="char* chPtr3 // Local Variable"&gt;chPtr3&lt;/a&gt;)) != *(((&lt;a title="System.Int32" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Int32"&gt;int&lt;/a&gt;*) &lt;a title="char* chPtr4 // Local Variable"&gt;chPtr4&lt;/a&gt;))) || (*(((&lt;a title="System.Int32" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Int32"&gt;int&lt;/a&gt;*) (&lt;a title="char* chPtr3 // Local Variable"&gt;chPtr3&lt;/a&gt; + 2))) != *(((&lt;a title="System.Int32" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Int32"&gt;int&lt;/a&gt;*) (&lt;a title="char* chPtr4 // Local Variable"&gt;chPtr4&lt;/a&gt; + 2))))) || ((*(((&lt;a title="System.Int32" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Int32"&gt;int&lt;/a&gt;*) (&lt;a title="char* chPtr3 // Local Variable"&gt;chPtr3&lt;/a&gt; + 4))) != *(((&lt;a title="System.Int32" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Int32"&gt;int&lt;/a&gt;*) (&lt;a title="char* chPtr4 // Local Variable"&gt;chPtr4&lt;/a&gt; + 4)))) || (*(((&lt;a title="System.Int32" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Int32"&gt;int&lt;/a&gt;*) (&lt;a title="char* chPtr3 // Local Variable"&gt;chPtr3&lt;/a&gt; + 6))) != *(((&lt;a title="System.Int32" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Int32"&gt;int&lt;/a&gt;*) (&lt;a title="char* chPtr4 // Local Variable"&gt;chPtr4&lt;/a&gt; + 6)))))) || (*(((&lt;a title="System.Int32" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Int32"&gt;int&lt;/a&gt;*) (&lt;a title="char* chPtr3 // Local Variable"&gt;chPtr3&lt;/a&gt; + 8))) != *(((&lt;a title="System.Int32" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Int32"&gt;int&lt;/a&gt;*) (&lt;a title="char* chPtr4 // Local Variable"&gt;chPtr4&lt;/a&gt; + 8)))))&lt;br&gt;                {&lt;br&gt;                    break;&lt;br&gt;                }&lt;br&gt;                &lt;a title="char* chPtr3 // Local Variable"&gt;chPtr3&lt;/a&gt; += 10;&lt;br&gt;                &lt;a title="char* chPtr4 // Local Variable"&gt;chPtr4&lt;/a&gt; += 10;&lt;br&gt;                &lt;a title="int length // Local Variable"&gt;length&lt;/a&gt; -= 10;&lt;br&gt;            }&lt;br&gt;            while (&lt;a title="int length // Local Variable"&gt;length&lt;/a&gt; &amp;gt; 0)&lt;br&gt;            {&lt;br&gt;                if (*(((&lt;a title="System.Int32" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Int32"&gt;int&lt;/a&gt;*) &lt;a title="char* chPtr3 // Local Variable"&gt;chPtr3&lt;/a&gt;)) != *(((&lt;a title="System.Int32" href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:2.0.0.0:b77a5c561934e089/System.Int32"&gt;int&lt;/a&gt;*) &lt;a title="char* chPtr4 // Local Variable"&gt;chPtr4&lt;/a&gt;)))&lt;br&gt;                {&lt;br&gt;                    break;&lt;br&gt;                }&lt;br&gt;                &lt;a title="char* chPtr3 // Local Variable"&gt;chPtr3&lt;/a&gt; += 2;&lt;br&gt;                &lt;a title="char* chPtr4 // Local Variable"&gt;chPtr4&lt;/a&gt; += 2;&lt;br&gt;                &lt;a title="int length // Local Variable"&gt;length&lt;/a&gt; -= 2;&lt;br&gt;            }&lt;br&gt;            return (&lt;a title="int length // Local Variable"&gt;length&lt;/a&gt; &amp;lt;= 0);&lt;br&gt;        }&lt;br&gt;    }&lt;br&gt;}&lt;br&gt;&lt;/pre&gt;&lt;br&gt;</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451256</link><pubDate>Sun, 04 Jan 2009 23:29:31 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451256</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451256/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Woweewow, did I ever get it wrong... I never thought that string comparison would be done via char-to-char comparison, but Reflector shows all... What the eff was that master string table I read about? Oh, well, here's what Reflector has to say about string comparison:


public static bool&amp;#8230;</evnet:previewtext><dc:creator>Minh</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451256/Trackback.aspx</trackback:ping></item><item><title>Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>&lt;P&gt;I think its that concatenation doesn't use the unmanaged string construction which handles interning&amp;nbsp; automatically, although I'm not sure why it does this, perhaps something related to performance of repeating concatenation.&lt;/P&gt;</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451219</link><pubDate>Sun, 04 Jan 2009 19:39:00 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451219</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451219/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>I think its that concatenation doesn't use the unmanaged string construction which handles interning&amp;nbsp; automatically, although I'm not sure why it does this, perhaps something related to performance of repeating concatenation.</evnet:previewtext><dc:creator>stevo_</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451219/Trackback.aspx</trackback:ping></item><item><title>Re: Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>Wow, did you get it wrong or not :).&lt;BR&gt;&lt;BR&gt;So, your a == b will be true but it's not "lighting fast" and it doesn't use the "master table" in any way. Since the == operator is overloaded for strings you get a normal character by character comparison, not a reference comparison. For claritiy&lt;BR&gt;&lt;BR&gt;Console.WriteLine("{0} {1}", a == b, Object.ReferenceEquals(a, b)); &lt;BR&gt;&lt;BR&gt;will print "true false".&lt;BR&gt;&lt;BR&gt;This "master table" actually exists but if you want to see its effects you need the following code:&lt;BR&gt;&lt;BR&gt;Console.WriteLine("{0} {1}", a == b, Object.ReferenceEquals(a, String.Intern(b))); &lt;BR&gt;&lt;BR&gt;This should print "true true". If it doesn't then&amp;nbsp;it means the runtime didn't automatically intern the string literals from the assembly and you need to intern the a string too.&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451214</link><pubDate>Sun, 04 Jan 2009 18:45:42 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451214</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451214/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Wow, did you get it wrong or not :).So, your a == b will be true but it's not "lighting fast" and it doesn't use the "master table" in any way. Since the == operator is overloaded for strings you get a normal character by character comparison, not a reference comparison. For&amp;#8230;</evnet:previewtext><dc:creator>Dexter</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451214/Trackback.aspx</trackback:ping></item><item><title>Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>I think here's why it doesn't matter:&lt;br&gt;&lt;br&gt;(this is going off memory, but I think it's accurate)&lt;br&gt;There's a run-time master table of all strings for a .Net app. This is required to implement .Net string immutability system (compare = fast, change = slow). So if you have code like this:&lt;br&gt;&lt;br&gt;string a = "123";&lt;br&gt;string b = "12";&lt;br&gt;&lt;br&gt;b = b + "3";&lt;br&gt;&lt;br&gt;// At this point a &amp;amp; b share the same reference&lt;br&gt;// The process involves evaluating b to "123" and doing a look up in the master string table&lt;br&gt;// and matching b w/ a pre-existing entry (a = "123")&lt;br&gt;&lt;br&gt;if (a == b) { ... }&lt;br&gt;&lt;br&gt;// Making the above comparison lighting fast&lt;br&gt;&lt;br&gt;OK, if you look into the static constructor of the String class, you'll see this:&lt;br&gt;&lt;br&gt;mscorlib / CommonLanguageRuntimeLibrary / System / String&lt;br&gt;&lt;br&gt;static String()&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp; Empty = "";&lt;br&gt;&amp;nbsp;&amp;nbsp; ...&lt;br&gt;}&lt;br&gt;&lt;br&gt;you'll see that an "empty" string value is entered into the master string table very early on, so that comparisons such as&lt;br&gt;&lt;br&gt;if (a == "")&lt;br&gt;&lt;br&gt;or &lt;br&gt;&lt;br&gt;if (a == String.Empty)&lt;br&gt;&lt;br&gt;is making a comparison the the exact same entry of the table...&lt;br&gt;&lt;br&gt;I imagine this functionality is built into the ldstr opcode&lt;br&gt;</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451197</link><pubDate>Sun, 04 Jan 2009 17:07:46 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451197</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451197/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>I think here's why it doesn't matter:(this is going off memory, but I think it's accurate)There's a run-time master table of all strings for a .Net app. This is required to implement .Net string immutability system (compare = fast, change = slow). So if you have code like this:string a =&amp;#8230;</evnet:previewtext><dc:creator>Minh</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451197/Trackback.aspx</trackback:ping></item><item><title>Re: Re: Re: Re: Re: Re: Re: Re: Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>Yeah, it's pretty flexible. It only has to "look like" IEnumerable. I was a bit surprised by the lack of decimal literals.</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451078</link><pubDate>Sat, 03 Jan 2009 13:12:08 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451078</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451078/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Yeah, it's pretty flexible. It only has to "look like" IEnumerable. I was a bit surprised by the lack of decimal literals.</evnet:previewtext><dc:creator>Tommy Carlier</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451078/Trackback.aspx</trackback:ping></item><item><title>Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>Btw. Since we are on the topic. Couldn't something like "" vs string.Empty be optimized by the JITter? I mean the whole code is compiled again... something like this could easily be done by the just-in-time compiler... Most people always forget that there's another guy involved after the MSIL has been generated by the C# compiler.</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451065</link><pubDate>Sat, 03 Jan 2009 10:23:06 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451065</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451065/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Btw. Since we are on the topic. Couldn't something like "" vs string.Empty be optimized by the JITter? I mean the whole code is compiled again... something like this could easily be done by the just-in-time compiler... Most people always forget that there's another guy involved after the MSIL has&amp;#8230;</evnet:previewtext><dc:creator>Christian Liensberger</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451065/Trackback.aspx</trackback:ping></item><item><title>Re: Re: Re: Re: Re: Re: Re: Re: Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>I love how enums are defined in the specs... with the special __value field. I couldn't blieve it when reading. But we're there probably at a level where this needs to be speced that way... After having known that it was obvious why I could set an enum value to everything through reflection.</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451064</link><pubDate>Sat, 03 Jan 2009 10:20:24 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451064</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451064/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>I love how enums are defined in the specs... with the special __value field. I couldn't blieve it when reading. But we're there probably at a level where this needs to be speced that way... After having known that it was obvious why I could set an enum value to everything through reflection.</evnet:previewtext><dc:creator>Christian Liensberger</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451064/Trackback.aspx</trackback:ping></item><item><title>Re: Re: Re: Re: Re: Re: Re: Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>Well try foreach on an object that has not the IEnumerable interface implemented but rather only exposes a GetEnumerator method... will work fine. Nice hack, isn't it?</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451063</link><pubDate>Sat, 03 Jan 2009 10:17:57 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451063</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451063/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Well try foreach on an object that has not the IEnumerable interface implemented but rather only exposes a GetEnumerator method... will work fine. Nice hack, isn't it?</evnet:previewtext><dc:creator>Christian Liensberger</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451063/Trackback.aspx</trackback:ping></item><item><title>Re: Re: Re: Re: Re: Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>Well... it depends. Since even comparing "" with string.Empty by calling the object.ReferenceEquals method returns true they both might actually represent the same objects on the heap... this could be optimized inside the CLR.&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;All the checks of evildictaitor result in "true" for me over here (same as Sven)... .NET 3.5 SP1 x86&lt;/div&gt;</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451062</link><pubDate>Sat, 03 Jan 2009 10:14:23 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451062</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451062/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Well... it depends. Since even comparing "" with string.Empty by calling the object.ReferenceEquals method returns true they both might actually represent the same objects on the heap... this could be optimized inside the CLR.All the checks of evildictaitor result in "true" for me over here (same as Sven)... .NET 3.5 SP1 x86</evnet:previewtext><dc:creator>Christian Liensberger</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451062/Trackback.aspx</trackback:ping></item><item><title>Re: Re: Re: Re: Re: Re: Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>&lt;blockquote&gt;&lt;div&gt;It's definitely False over here.&lt;/div&gt;&lt;/blockquote&gt;&lt;BR&gt;It's true here, Vista x64, .Net 3.5 SP1.&lt;BR&gt;&lt;BR&gt;As for str == "" versus str.Length == 0, I've always been told the latter performs better though I've never checked it myself. If there's a chance of str being null, using string.IsNullOrEmpty(str) is best of course.&lt;BR&gt;&lt;BR&gt;Visual Basic throws some mud into the water since doing str = "" (comparison, not assignment) is actually treated as a special case by the compiler which also evaluates true if str is null (Nothing), similar to string.IsNullOrEmpty(). I never know whether I should comment on that when I use it, since it's a language feature and I don't like writing comments to explain language features, but&amp;nbsp;very few people actually know about this one, and C# developers trying to read VB code will definitely not know about it and might think it's a bug.</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451055</link><pubDate>Sat, 03 Jan 2009 08:00:13 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451055</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451055/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>It's definitely False over here.It's true here, Vista x64, .Net 3.5 SP1.As for str == "" versus str.Length == 0, I've always been told the latter performs better though I've never checked it myself. If there's a chance of str being null, using string.IsNullOrEmpty(str) is best of course.Visual Basic&amp;#8230;</evnet:previewtext><dc:creator>Sven Groot</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451055/Trackback.aspx</trackback:ping></item><item><title>Re: Re: Re: Re: Re: Re: Re: Re: Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>Interesting discussion, learning a lot from this.&lt;br&gt;</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451045</link><pubDate>Sat, 03 Jan 2009 03:31:52 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451045</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451045/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Interesting discussion, learning a lot from this.</evnet:previewtext><dc:creator>Donald Adu-Poku</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451045/Trackback.aspx</trackback:ping></item><item><title>Re: Re: Re: Re: Re: Re: Re: Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>Those are defined as part of the C# Ecma specification. String.Empty isn't.&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;The compiler demands all of the primitives (byte,sbyte,char,string,int16,int32,int64,uint16,uint32,uint64,intptr,uintptr,bool and void), the metatypes (delegate, multicastdelegate, valuetype,object,enum,array), some special types (exception, runtimehandles) some compiler directives (paramsarrayattribute,outattribute) and the interfaces IEnumerable, IDisposable, IEnumerator (with appropriate types on the interfaces) to be defined as part of the ECMA standard for C#. Most everything else in C# is library and syntax sugar.&lt;/div&gt;</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451006</link><pubDate>Fri, 02 Jan 2009 22:17:18 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=451006</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/451006/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Those are defined as part of the C# Ecma specification. String.Empty isn't.The compiler demands all of the primitives (byte,sbyte,char,string,int16,int32,int64,uint16,uint32,uint64,intptr,uintptr,bool and void), the metatypes (delegate, multicastdelegate, valuetype,object,enum,array), some special&amp;#8230;</evnet:previewtext><dc:creator>evildictaitor</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/451006/Trackback.aspx</trackback:ping></item><item><title>Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>&lt;P&gt;Inteesting stuff guys, thanks.&lt;/P&gt;</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=450988</link><pubDate>Fri, 02 Jan 2009 19:54:51 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=450988</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/450988/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Inteesting stuff guys, thanks.</evnet:previewtext><dc:creator>Bas</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/450988/Trackback.aspx</trackback:ping></item><item><title>Re: Re: Re: Re: Re: Re: Re: Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>&lt;P&gt;Actually I don't think the C# compiler is aware of IEnumerable (I could be wrong), the foreach really just looks for a member called GetEnumerator() that returns an object that has the members MoveNext and Current (with applicable access and signatures).&lt;/P&gt;</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=450986</link><pubDate>Fri, 02 Jan 2009 19:41:17 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=450986</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/450986/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>Actually I don't think the C# compiler is aware of IEnumerable (I could be wrong), the foreach really just looks for a member called GetEnumerator() that returns an object that has the members MoveNext and Current (with applicable access and signatures).</evnet:previewtext><dc:creator>stevo_</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/450986/Trackback.aspx</trackback:ping></item><item><title>Re: Re: Re: Re: Re: Re: Re: Why doesn't the C# compiler turn "" into string.Empty?</title><description>I think you'll find project specific extensions become part of the compilation process.. these already happen today as part of 3rd party tools that pull apart IL and re-assemble it (post sharp for example). You seem to be confusing your process of building a compiler with what the extension points in the managed C# compiler will let you do.. its already been demonstated how the .NET C# compiler will work, being able to read source and get a tree that you can freely transform, or even build a tree manually (if you really wanted), then compilation units to take that tree and produce IL.</description><comments></comments><link>http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=450985</link><pubDate>Fri, 02 Jan 2009 19:36:59 GMT</pubDate><guid isPermaLink="false">http://channel9.msdn.com/forums/TechOff/450791-Why-doesnt-the-C-compiler-turn--into-stringEmpty/?CommentID=450985</guid><evnet:views>0</evnet:views><evnet:viewtrackingurl>http://channel9.msdn.com/450985/WebViewBug.aspx?EVT=0</evnet:viewtrackingurl><evnet:previewtext>I think you'll find project specific extensions become part of the compilation process.. these already happen today as part of 3rd party tools that pull apart IL and re-assemble it (post sharp for example). You seem to be confusing your process of building a compiler with what the extension points&amp;#8230;</evnet:previewtext><dc:creator>stevo_</dc:creator><slash:comments>0</slash:comments><wfw:commentRss></wfw:commentRss><trackback:ping>http://channel9.msdn.com/450985/Trackback.aspx</trackback:ping></item></channel></rss>