<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.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>the blog =&gt; anything goes : C# 3.0</title><link>http://msmvps.com/blogs/senthil/archive/tags/C_2300_+3.0/default.aspx</link><description>Tags: C# 3.0</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>When a C++ destructor did not run – Part 1</title><link>http://msmvps.com/blogs/senthil/archive/2009/12/04/when-a-c-destructor-did-not-run-part-1.aspx</link><pubDate>Fri, 04 Dec 2009 06:01:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1743594</guid><dc:creator>Senthil</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/rsscomments.aspx?PostID=1743594</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/commentapi.aspx?PostID=1743594</wfw:comment><comments>http://msmvps.com/blogs/senthil/archive/2009/12/04/when-a-c-destructor-did-not-run-part-1.aspx#comments</comments><description>&lt;p&gt;Consider this piece of C++ code.&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#ffffff;width:100%;font-family:&amp;#39;Consolas&amp;#39;,&amp;#39;Courier New&amp;#39;,monospace;direction:ltr;color:black;font-size:8pt;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;namespace&lt;/span&gt; std;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; C&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt; {&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;:&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;     C() &lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;     { &lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;         cout &amp;lt;&amp;lt; &lt;span style="color:#006080;"&gt;&amp;quot;Constructed&amp;quot;&lt;/span&gt;; &lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;     }&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;     ~C() &lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;     { &lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;         cout &amp;lt;&amp;lt; &lt;span style="color:#006080;"&gt;&amp;quot;Destructed&amp;quot;&lt;/span&gt;; &lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;     }&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt; };&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; SomeFunc()&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#606060;" id="lnum17"&gt;  17:&lt;/span&gt; {&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#606060;" id="lnum18"&gt;  18:&lt;/span&gt;     C c;&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#606060;" id="lnum19"&gt;  19:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; std::exception(&lt;span style="color:#006080;"&gt;&amp;quot;Gone&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;"&gt;&lt;span style="color:#606060;" id="lnum20"&gt;  20:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If you know any C++ at all, you&amp;rsquo;ll know that when SomeFunc returns, both &amp;ldquo;Constructed&amp;rdquo; and &amp;ldquo;Destructed&amp;rdquo; will be printed to the console. That is because C++ guarantees that the destructor of an object created on the stack will always run when control leaves the scope, no matter what, and &lt;a href="http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization" target="_blank"&gt;RAII&lt;/a&gt; depends on that fact.&lt;/p&gt;
&lt;p&gt;You put all this code is in a static library, say PureCPP.lib, and you compile it with the /EHs option, because you want to use C++ exceptions.&lt;/p&gt;
&lt;p&gt;You then write a native application to consume this library, statically link to it, and everything works great.&lt;/p&gt;
&lt;p&gt;One day, you wake up and realize you&amp;rsquo;ll have to try out this .NET stuff that everyone is talking about. You discover that there&amp;rsquo;s this language called C++/CLI that&amp;rsquo;s great for interfacing with native code. So you fire up VS, create a CLR console application that calls SomeFunc, and link PureCPP.lib against it.&lt;/p&gt;
&lt;p&gt;Just when you&amp;rsquo;re wondering how easy things turned out to be, you notice something strange. There&amp;rsquo;s something missing in the console output. When you figure out what&amp;rsquo;s missing, your jaw hits the ground. Mine did too, when I realized that it was the &amp;ldquo;Destructed&amp;rdquo; part that was missing. Which means the impossible just happened - the destructor for class C did not run.&lt;/p&gt;
&lt;p&gt;What followed was a long and exciting journey into the world of SEH (Structured Exception Handling), exception codes and exception propagation and handling by the CLR versus C++. All that in the &lt;a href="http://msmvps.com/blogs/senthil/archive/2009/12/05/when-a-c-destructor-did-not-run-part-2.aspx"&gt;next part&lt;/a&gt; &amp;ndash; stay tuned.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1743594" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/senthil/archive/tags/software/default.aspx">software</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/Debugging/default.aspx">Debugging</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/CodeProject/default.aspx">CodeProject</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/Windbg/default.aspx">Windbg</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2B002B00_/default.aspx">C++</category></item><item><title>Wrong compiler warning? Or Not?</title><link>http://msmvps.com/blogs/senthil/archive/2009/11/30/wrong-compiler-warning-or-not.aspx</link><pubDate>Tue, 01 Dec 2009 05:27:57 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1743147</guid><dc:creator>Senthil</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/rsscomments.aspx?PostID=1743147</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/commentapi.aspx?PostID=1743147</wfw:comment><comments>http://msmvps.com/blogs/senthil/archive/2009/11/30/wrong-compiler-warning-or-not.aspx#comments</comments><description>&lt;p&gt;This piece of code results in a warning.&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#ffffff;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Consolas&amp;#39;, &amp;#39;Courier New&amp;#39;, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Test&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; obj = &lt;span style="color:#006080;"&gt;&amp;quot;Senthil&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; myName = &lt;span style="color:#006080;"&gt;&amp;quot;Senthil&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;         Console.WriteLine(obj == myName);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The compiler says “warning CS0252: Possible unintended reference comparison; to get a value comparison, cast the left hand side to type &amp;#39;string&amp;#39;” on line 7. The compiler is right; it has no way of knowing that obj is actually a string. It infers the static type of obj to be System.Object, and if you’ve done any programming in C# at all, you’ll know that the default behavior of the == operator is reference comparison. This code is unintentionally comparing reference values of two local variables, and that’s what the compiler is warning about.&lt;/p&gt;

&lt;p&gt;Yet try running the code, and you’ll see that it works correctly; it prints True. Is the compiler wrong?&lt;/p&gt;

&lt;p&gt;No. The code appears to work fine because &lt;a href="http://msdn.microsoft.com/en-us/library/system.string.intern.aspx" target="_blank"&gt;string interning&lt;/a&gt; masks the problem. The C# compiler figures that there are two constant strings in the program, and both are equal, so instead of creating two distinct string objects, it creates only one. With strings being immutable, reusing string objects for identical strings is safe. And that’s why this code works, both obj and myName refer to the same string object, which means reference comparison will succeed.&lt;/p&gt;

&lt;p&gt;Now that we know why it’s working, it’s easy to prove that the compiler warning is right with a small code change.&lt;/p&gt;

&lt;div&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#ffffff;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Consolas&amp;#39;, &amp;#39;Courier New&amp;#39;, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Test&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; obj = &lt;span style="color:#006080;"&gt;&amp;quot;Senthil&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; myName1 = &lt;span style="color:#006080;"&gt;&amp;quot;Sen&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; myName2 = &lt;span style="color:#006080;"&gt;&amp;quot;thil&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; myName = myName1 + myName2;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;         Console.WriteLine(obj == myName);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div&gt;&amp;#160;&lt;/div&gt;

&lt;div&gt;Constructing myName dynamically forces the compiler to create another string object; it cannot reuse the interned one. As you’d expect, this piece of code will print False.&lt;/div&gt;

&lt;p&gt;Fixing the warning is a mere matter of casting obj to the correct type (string) and then doing the equality check.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#ffffff;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Consolas&amp;#39;, &amp;#39;Courier New&amp;#39;, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Test&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; obj = &lt;span style="color:#006080;"&gt;&amp;quot;Senthil&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; myName1 = &lt;span style="color:#006080;"&gt;&amp;quot;Sen&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; myName2 = &lt;span style="color:#006080;"&gt;&amp;quot;thil&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; myName = myName1 + myName2;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;         Console.WriteLine(((&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;)obj) == myName);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Or we could use the Equals method, which is virtual and won’t be fooled by the compile time type.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#ffffff;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Consolas&amp;#39;, &amp;#39;Courier New&amp;#39;, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Test&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; obj = &lt;span style="color:#006080;"&gt;&amp;quot;Senthil&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; myName1 = &lt;span style="color:#006080;"&gt;&amp;quot;Sen&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; myName2 = &lt;span style="color:#006080;"&gt;&amp;quot;thil&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; myName = myName1 + myName2;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;         Console.WriteLine(obj.Equals(myName));&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Both of them print True, which is what we want.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1743147" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/senthil/archive/tags/software/default.aspx">software</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>When what you set is not what you get : SetEnvironmentVariable and getenv</title><link>http://msmvps.com/blogs/senthil/archive/2009/10/13/when-what-you-set-is-not-what-you-get-setenvironmentvariable-and-getenv.aspx</link><pubDate>Tue, 13 Oct 2009 06:14:12 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1732109</guid><dc:creator>Senthil</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/rsscomments.aspx?PostID=1732109</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/commentapi.aspx?PostID=1732109</wfw:comment><comments>http://msmvps.com/blogs/senthil/archive/2009/10/13/when-what-you-set-is-not-what-you-get-setenvironmentvariable-and-getenv.aspx#comments</comments><description>&lt;p&gt;Mixing SetEnvironmentVariable and getenv is asking for trouble, as we recently found to our dismay (and exasperation!). It took some serious debugging to figure out the actual problem – let’s see if you can figure it out.&lt;/p&gt;  &lt;p&gt;Here’s some C++/CLI code that uses getenv to read the value of an environment variable and print it to the console.&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#ffffff;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Consolas&amp;#39;, &amp;#39;Courier New&amp;#39;, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; ref &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; EnvironmentVariablePrinter&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;:&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; PrintEnv(String ^key)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;         {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;              IntPtr ptr = Marshal::StringToHGlobalAnsi(key);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;              &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;char&lt;/span&gt; *ckey = (&lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;char&lt;/span&gt; *)ptr.ToPointer();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;              &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;char&lt;/span&gt; *cval = getenv(ckey);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;              string val = cval == NULL ? &lt;span style="color:#006080;"&gt;&amp;quot;&amp;quot;&lt;/span&gt; : string(cval);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;              cout &amp;lt;&amp;lt; &lt;span style="color:#006080;"&gt;&amp;quot;Key is &amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; ckey &amp;lt;&amp;lt; &lt;span style="color:#006080;"&gt;&amp;quot; and value is &amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; val;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;              Marshal::FreeHGlobal(ptr);    &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt;         }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt; };&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;PrintEnv merely converts the .NET string into an unmanaged one and calls getenv, printing the returned value to the console.&lt;/p&gt;

&lt;p&gt;And here’s some C# code that tests the class.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#ffffff;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Consolas&amp;#39;, &amp;#39;Courier New&amp;#39;, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Test&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; key = &lt;span style="color:#006080;"&gt;&amp;quot;MyKey&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;         Environment.SetEnvironmentVariable(key, &lt;span style="color:#006080;"&gt;&amp;quot;MyValue&amp;quot;&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;         PrintValue();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; PrintValue()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;         EnvironmentVariablePrinter er = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; EnvironmentVariablePrinter();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;         er.PrintEnv(key);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The code uses System.Environment.SetEnvironmentVariable to set the value of the variable and then calls the C++/CLI code to verify that it prints the correct value. And of course, being written in different languages, the two pieces of code must reside in different projects, say CPlusPlusLib.dll and ConsoleApplication.exe, with the latter referencing the former.&lt;/p&gt;

&lt;p&gt;No surprises here - this works as expected and prints “Key is MyKey and value is MyValue”.&lt;/p&gt;

&lt;p&gt;However, a seemingly harmless change breaks the code big time.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#ffffff;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Consolas&amp;#39;, &amp;#39;Courier New&amp;#39;, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Test&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; key = &lt;span style="color:#006080;"&gt;&amp;quot;MyKey&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;         Environment.SetEnvironmentVariable(key, &lt;span style="color:#006080;"&gt;&amp;quot;MyValue&amp;quot;&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;         EnvironmentVariablePrinter er = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; EnvironmentVariablePrinter();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;         er.PrintEnv(key);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;All I’ve done is inlining of PrintValue, yet running this code prints “Key is MyKey and value is” – getenv is now returning NULL instead of “MyValue”.&lt;/p&gt;

&lt;p&gt;It gets even more interesting.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#ffffff;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Consolas&amp;#39;, &amp;#39;Courier New&amp;#39;, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Test&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; key = &lt;span style="color:#006080;"&gt;&amp;quot;MyKey&amp;quot;&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;         Environment.SetEnvironmentVariable(key, &lt;span style="color:#006080;"&gt;&amp;quot;MyValue&amp;quot;&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;         EnvironmentVariablePrinter er = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;         PrintValue(); &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; PrintValue()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;         EnvironmentVariablePrinter er = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; EnvironmentVariablePrinter();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt;         er.PrintEnv(key);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;This doesn’t work either – the mere declaration of EnvironmentVariablePrinter inside Main makes getenv return NULL for “MyKey”. This can’t be good, can it? &lt;/p&gt;

&lt;p&gt;Actually yes, because that is a valuable clue – it means the change in behavior has something to do with JITting. As long as all code that references EnvironmentVariablePrinter is in a separate method, everything works fine (in debug mode, atleast). Things start going south when any such code is in Main itself.&lt;/p&gt;

&lt;p&gt;What would the JITter do differently in the two scenarios? Load the assembly containing EnvironmentVariablePrinter (CPlusPlusLib.dll) at different times, of course. When all code referencing EnvironmmentVariablePrinter is inside PrintValue, it will have to load the DLL only when JITting PrintValue, whereas in the other case, it will have to load it when JITting Main. JITting Main obviously occurs much before JITting PrintValue, so DLL load time (relative to other code) is one big difference between the two scenarios that occurs because of JITting.&lt;/p&gt;

&lt;p&gt;Why would loading CPlusPlusLib.dll a little early make getenv return NULL?&lt;/p&gt;

&lt;p&gt;To understand that, you’ll first have to know how the getenv function works. Windows has APIs to set and get environment variables (SetEnvironmentVariable/GetEnvironmentVariable), and the .NET method P/Invokes into the Windows API to set and get values. getenv, on the other hand, is a CRT function, and does not delegate to the Windows API. Instead, the CRT gets all environment variables and their values when it is starting up (using the GetEnvironmentStrings Windows API), and copies them into its own data structures (MSVCR80!environ). getenv then works on the copied data from then on.&lt;/p&gt;

&lt;p&gt;Now do you see the problem? When CPlusPlusLib.dll is loaded early (when JITting Main), the CRT also gets loaded as one of its dependencies, and the startup code that copies environment variables runs right away. At that point, Main hasn’t even been JITted yet, so there’s no way our call to System.Environment.SetEnvironmentVariable could have run by that time. And when it actually runs, it’s too late – the CRT environ block would have been updated much earlier, and calling the Windows API’s SetEnvironmentVariable wouldn’t have any effect on the cached values. When getenv runs, it looks in the cached values and returns NULL.&lt;/p&gt;

&lt;p&gt;It’s easy to see why it works in the first case now – CRT loading occurs when JITting PrintValue, and that occurs after our call to SetEnvironmentVariable has executed. Which means that when it calls GetEnvironmentStrings as part of startup, it gets the variable (and its value) that we just set.&lt;/p&gt;

&lt;p&gt;Nasty, ain’t it? The actual scenario was a lot more messy – things suddenly stopped working when we linked to a DLL ported to VS2008. We actually figured the problem backwards – we first saw that the CRT load time was different, theorized how getenv works, verified the theory by stepping through the assembly code and looking at the environ block, and once we realized the problem, figured out what was causing early loading of the CRT. Windbg was awesome for debugging this - things would have been very difficult if not for sxe ld:MSVCR90 and x MSVCR80!environ.&lt;/p&gt;

&lt;p&gt;The fix was rather simple - in our case, we merely had to move code that set environment variable before CRT load. There’s another twist though; mscorwks.dll, which is the heart of the CLR, loads MSVCR80 when it loads, and you can’t set your environment variables before that, not from managed code anyway. Fortunately, in our case, the getenv call is from a library that links to MSVCR90, so as long as we set the environment variable before that version of the CRT loads, we’re good to go. Until the CLR gets linked to MSVCR90, anyway :).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1732109" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/senthil/archive/tags/software/default.aspx">software</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/Debugging/default.aspx">Debugging</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/CodeProject/default.aspx">CodeProject</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/Windbg/default.aspx">Windbg</category></item><item><title>Anonymous methods as event handlers – Part 2</title><link>http://msmvps.com/blogs/senthil/archive/2009/09/09/anonymous-methods-as-event-handlers-part-2.aspx</link><pubDate>Wed, 09 Sep 2009 05:02:26 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1721750</guid><dc:creator>Senthil</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/rsscomments.aspx?PostID=1721750</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/commentapi.aspx?PostID=1721750</wfw:comment><comments>http://msmvps.com/blogs/senthil/archive/2009/09/09/anonymous-methods-as-event-handlers-part-2.aspx#comments</comments><description>&lt;p&gt;The &lt;a href="http://msmvps.com/blogs/senthil/archive/2009/09/01/anonymous-methods-as-event-handlers-part-1.aspx"&gt;previous post&lt;/a&gt; discussed having anonymous methods as event handlers and ended with a question – why doesn’t unsubscription work while subscription works out alright?&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/senthil/archive/2009/09/01/anonymous-methods-as-event-handlers-part-1.aspx#1720078"&gt;Vivek&lt;/a&gt; got the answer spot on – the way the C# compiler handles and translates anonymous methods is the reason.&lt;/p&gt;  &lt;p&gt;Here’s the code involved.&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#ffffff;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Consolas&amp;#39;, &amp;#39;Courier New&amp;#39;, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Initialize()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     control.KeyPressed += IfEnabledThenDo(control_KeyPressed);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     control.MouseMoved += IfEnabledThenDo(control_MouseMoved);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt; }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Destroy()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;     control.KeyPressed -= IfEnabledThenDo(control_KeyPressed);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;     control.MouseMoved -= IfEnabledThenDo(control_MouseMoved);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt; }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; EventHandler&amp;lt;Control.ControlEventArgs&amp;gt; IfEnabledThenDo(EventHandler&amp;lt;Control.ControlEventArgs&amp;gt; actualAction)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (sender, args) =&amp;gt; { &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (args.Control.Enabled) actualAction(sender, args); };&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The compiler translates &lt;font color="#0000ff"&gt;IfEnabledThenDo&lt;/font&gt; into this&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#ffffff;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Consolas&amp;#39;, &amp;#39;Courier New&amp;#39;, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; EventHandler&amp;lt;Control.ControlEventArgs&amp;gt; IfEnabledThenDo(EventHandler&amp;lt;Control.ControlEventArgs&amp;gt; actualAction)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &amp;lt;&amp;gt;c__DisplayClass1 CS$&amp;lt;&amp;gt;8__locals2 = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &amp;lt;&amp;gt;c__DisplayClass1();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     CS$&amp;lt;&amp;gt;8__locals2.actualAction = actualAction;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; EventHandler&amp;lt;Control.ControlEventArgs&amp;gt;(CS$&amp;lt;&amp;gt;8__locals2.&amp;lt;IfEnabledThenDo&amp;gt;b__0);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Now the problem should be fairly obvious – every time the function is called, a new object gets created, and the event handler returned actually refers to a method (&lt;font color="#0000ff"&gt;&amp;lt;IfEnabledThenDo&amp;gt;b__0&lt;/font&gt;) on the new instance. And that’s what breaks unsubscription. &lt;font color="#0000ff"&gt;–=&lt;/font&gt; will not remove a delegate of a different instance of the same class from the invocation list – if it did, the consequences would not be pleasant if multiple instances of the same class subscribe to an event.&lt;/p&gt;

&lt;p&gt;But why does the compiler translate our lambda expression this way? &lt;a href="http://blogs.msdn.com/oldnewthing/archive/2006/08/02/686456.aspx"&gt;Raymond Chen&lt;/a&gt; has a great blog post explaining why, but the short answer is that it is needed to “hold” &lt;font color="#0000ff"&gt;actualAction&lt;/font&gt; (the method parameter to IfEnabledThenDo) so that it is available when the event handler actually executes.&lt;/p&gt;

&lt;p&gt;Now that we know why, the way to get around this issue is to cache the delegate instance returned by &lt;font color="#0000ff"&gt;IfEnabledThenDo&lt;/font&gt; and use the same instance for subscription and unsubscription.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#ffffff;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Consolas&amp;#39;, &amp;#39;Courier New&amp;#39;, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; EventHandler&amp;lt;Control.ControlEventArgs&amp;gt; keyPressed;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; EventHandler&amp;lt;Control.ControlEventArgs&amp;gt; mouseMoved;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Initialize()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;    keyPressed = IfEnabledThenDo(control_KeyPressed);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;    mouseMoved = IfEnabledThenDo(control_MouseMoved);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;    control.KeyPressed += keyPressed;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;    control.MouseMoved += mouseMoved;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt; }        &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Destroy()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;    control.KeyPressed -= keyPressed;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt;    control.MouseMoved -= mouseMoved;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum17"&gt;  17:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Knowing how things work under the hood has its advantages, I guess :)&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;PS : A very small syntactic change to the original example would have made the code work right away. If you’ve followed along this far, you should be able to figure out why.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#ffffff;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Consolas&amp;#39;, &amp;#39;Courier New&amp;#39;, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Initialize()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;    actualAction = control_KeyPressed;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;    control.KeyPressed += IfEnabledThenDo();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt; }        &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Destroy()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;     control.KeyPressed -= IfEnabledThenDo();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt; }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt; EventHandler&amp;lt;Control.ControlEventArgs&amp;gt; actualAction;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; EventHandler&amp;lt;Control.ControlEventArgs&amp;gt; IfEnabledThenDo()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (sender, args) =&amp;gt; { &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (args.Control.Enabled) actualAction(sender, args); };&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1721750" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/senthil/archive/tags/software/default.aspx">software</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/CodeProject/default.aspx">CodeProject</category></item><item><title>Anonymous methods as event handlers – Part 1</title><link>http://msmvps.com/blogs/senthil/archive/2009/09/01/anonymous-methods-as-event-handlers-part-1.aspx</link><pubDate>Tue, 01 Sep 2009 20:22:40 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1719957</guid><dc:creator>Senthil</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/rsscomments.aspx?PostID=1719957</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/commentapi.aspx?PostID=1719957</wfw:comment><comments>http://msmvps.com/blogs/senthil/archive/2009/09/01/anonymous-methods-as-event-handlers-part-1.aspx#comments</comments><description>&lt;p&gt;The syntactic sugar offered by anonymous methods makes them great candidates for writing event handlers; together with smart type inference, they reduce the amount of code written by an order of magnitude.&lt;/p&gt;  &lt;p&gt;And that’s without considering the power offered by closures. With event handlers, closures allow you to kind of “stuff” extra parameters into the handler, without changing the actual number of formal parameters. This blog post shows a situation where an anonymous method acting as an event handler makes code simpler, and then goes on to show a gotcha with un-subscription and anonymous methods.&lt;/p&gt;  &lt;p&gt;Here’s a simple Control class that fires a bunch of events.&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#ffffff;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Consolas&amp;#39;, &amp;#39;Courier New&amp;#39;, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Control&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; ControlEventArgs : EventArgs&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; Control Control {get;set;}&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; Enabled { get; set; }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;event&lt;/span&gt; EventHandler&amp;lt;ControlEventArgs&amp;gt; KeyPressed;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;event&lt;/span&gt; EventHandler&amp;lt;ControlEventArgs&amp;gt; LeftButtonClicked;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;event&lt;/span&gt; EventHandler&amp;lt;ControlEventArgs&amp;gt; RightButtonClicked;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;event&lt;/span&gt; EventHandler&amp;lt;ControlEventArgs&amp;gt; MouseMoved;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Let’s say you’re developing a GUI application with this class, and you want to handle events only if the originating control is visually enabled i.e., Enabled set to true. Pretty reasonable constraint, but tedious to implement, if you go the standard way of adding the check to the start of each of your event handlers.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#ffffff;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Consolas&amp;#39;, &amp;#39;Courier New&amp;#39;, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; GUIApp&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Initialize()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;         Control control = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Control();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;         control.KeyPressed += &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; EventHandler&amp;lt;Control.ControlEventArgs&amp;gt;(control_KeyPressed);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;         control.MouseMoved += &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; EventHandler&amp;lt;Control.ControlEventArgs&amp;gt;(control_MouseMoved);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; control_MouseMoved(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, Control.ControlEventArgs e)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (e.Control.Enabled)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;         {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt;             &lt;span style="color:#008000;"&gt;/// &lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;         }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum17"&gt;  17:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum18"&gt;  18:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; control_KeyPressed(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, Control.ControlEventArgsEventArgs e)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum19"&gt;  19:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum20"&gt;  20:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (e.Control.Enabled)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum21"&gt;  21:&lt;/span&gt;         {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum22"&gt;  22:&lt;/span&gt;             &lt;span style="color:#008000;"&gt;///&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum23"&gt;  23:&lt;/span&gt;         }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum24"&gt;  24:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum25"&gt;  25:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;With an anonymous method, you could write a far more terse and easy to maintain version&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#ffffff;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Consolas&amp;#39;, &amp;#39;Courier New&amp;#39;, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; GUIApp&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Initialize()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;         Control control = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Control();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;         control.KeyPressed += IfEnabledThenDo(control_KeyPressed);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;         control.MouseMoved += IfEnabledThenDo(control_MouseMoved);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; EventHandler&amp;lt;Control.ControlEventArgs&amp;gt; IfEnabledThenDo(EventHandler&amp;lt;Control.ControlEventArgs&amp;gt; actualAction)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (sender, args) =&amp;gt; { &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (args.Control.Enabled) { actualAction(sender, args); } };&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; control_MouseMoved(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, Control.ControlEventArgs e)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum17"&gt;  17:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;///&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum18"&gt;  18:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum19"&gt;  19:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum20"&gt;  20:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; control_KeyPressed(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, Control.ControlEventArgs e)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum21"&gt;  21:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum22"&gt;  22:&lt;/span&gt;         &lt;span style="color:#008000;"&gt;///&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum23"&gt;  23:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum24"&gt;  24:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;IfEnabledThenDo returns an anonymous function that first checks whether the control is enabled before calling the actual function. The code is much shorter, and the condition is checked only in one place, which makes it easy to modify or add additional logic without having to remember to change every single event handler. Plus, the reads like an English statement – subscribe to the event and if enabled, then do whatever else is necessary.&lt;/p&gt;

&lt;p&gt;Great, but unless you are a masochist who revels in littering the code base with hard to reproduce bugs that bomb your app only when demoing to your most important customer, you must, of course, write code to unsubscribe. But there’s no method name to refer to, so you do it the same way as you did when subscribing.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#ffffff;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Consolas&amp;#39;, &amp;#39;Courier New&amp;#39;, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Initialize()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     control.KeyPressed += IfEnabledThenDo(control_KeyPressed);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     control.MouseMoved += IfEnabledThenDo(control_MouseMoved);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt; }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Destroy()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;     control.KeyPressed -= IfEnabledThenDo(control_KeyPressed);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;     control.MouseMoved -= IfEnabledThenDo(control_MouseMoved);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;This, unfortunately, won’t work – the application will still remain subscribed to those events. Can you figure out why?&lt;/p&gt;

&lt;p&gt;Answer and more in the next blog post.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1719957" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/senthil/archive/tags/software/default.aspx">software</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/CodeProject/default.aspx">CodeProject</category></item><item><title>Remoting IEnumerables</title><link>http://msmvps.com/blogs/senthil/archive/2009/08/29/remoting-ienumerables.aspx</link><pubDate>Sat, 29 Aug 2009 14:49:45 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1719111</guid><dc:creator>Senthil</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/rsscomments.aspx?PostID=1719111</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/commentapi.aspx?PostID=1719111</wfw:comment><comments>http://msmvps.com/blogs/senthil/archive/2009/08/29/remoting-ienumerables.aspx#comments</comments><description>&lt;p&gt;You&amp;#39;re writing this really cool and innovative class to calculate the first hundred thousand natural numbers. You think about the API, and you realize that returning an array of the numbers a) might take a long time to complete, and b) is going to cause memory usage to spike up like mad.&lt;/p&gt;  &lt;p&gt;So you decide to stream them instead, returning an IEnumerable&amp;lt;T&amp;gt; instance instead of an array. Being a crack C# developer, you use the incredibly powerful yield keyword, rather than rolling your own implementation of the IEnumerable&amp;lt;T&amp;gt; interface.&lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Consolas&amp;#39;, &amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#ffffff;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Consolas&amp;#39;, &amp;#39;Courier New&amp;#39;, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; MyCoolMathEngine&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IEnumerable&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt; GetFirstHundredThousandNaturalNumbers()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 100000; ++i)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;yield&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; i;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;People start downloading your class and it becomes so popular that they want you to host it in an external service, as a remote component.&lt;/p&gt;

&lt;p&gt;Fine, you say, and you pick .NET remoting to provide remote access. You pat yourself on the back for thinking ahead and using an enumerator model – it scales rather nicely. You write the plumbing code to host the class, and with a victorious smile on your lips, you write a test client that instantiates and accesses the method.&lt;/p&gt;

&lt;p&gt;Only to find that it crashes with a System.Runtime.Serialization.SerializationException that says a type that you &lt;strong&gt;didn’t even write&lt;/strong&gt; is not marked serializable.&lt;/p&gt;

&lt;p&gt;That’s when it hits you, or at least that’s when it hit me, when I was modifying &lt;a href="http://undisposed.codeplex.com/SourceControl/changeset/view/24897#265185"&gt;FinalizeTypeFinder&lt;/a&gt; to get it load on a different AppDomain.&lt;/p&gt;

&lt;p&gt;Because yield return was used, what actually gets back to the caller is an instance of a compiler generated class that implements IEnumerable&amp;lt;int&amp;gt;, and that autogenerated class is not marked serializable. Nor does it derive from MarshalByRefObject, so there’s no way it can be remoted.&lt;/p&gt;

&lt;p&gt;The only real solution I can think of is to write a custom implementation of IEnumerable&amp;lt;T&amp;gt;, like we had to do back in the C# 1.1 days. &lt;a href="http://msmvps.com/blogs/senthil/archive/2009/07/03/volatile-and-local.aspx"&gt;Yet another instance&lt;/a&gt; where compiler magic doesn’t quite work out in a particular scenario, I suppose.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1719111" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/senthil/archive/tags/software/default.aspx">software</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Overload resolution and null</title><link>http://msmvps.com/blogs/senthil/archive/2009/07/08/overload-resolution-and-null.aspx</link><pubDate>Wed, 08 Jul 2009 06:28:15 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1698685</guid><dc:creator>Senthil</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/rsscomments.aspx?PostID=1698685</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/commentapi.aspx?PostID=1698685</wfw:comment><comments>http://msmvps.com/blogs/senthil/archive/2009/07/08/overload-resolution-and-null.aspx#comments</comments><description>&lt;p&gt;My colleague &lt;a title="http://soundararajan0.spaces.live.com/" href="http://soundararajan0.spaces.live.com/"&gt;Soundar&lt;/a&gt; discovered this rather interesting behavior.&lt;/p&gt;  &lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  1: &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Test
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  2: {
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  3:     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main()
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  4:     {
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  5:         Test test = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  6: 
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  7:         Console.WriteLine(&amp;quot;&lt;span style="color:#8b0000;"&gt;{0}&lt;/span&gt;&amp;quot;, test);
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  8:         Console.WriteLine(&amp;quot;&lt;span style="color:#8b0000;"&gt;{0}&lt;/span&gt;&amp;quot;, &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  9:     }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt; 10: }&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;If you run this code, you’ll find that while line 7 prints an empty line, line 8 causes an ArgumentNullException. Note that the test reference is also null, so it should certainly surprise you that the two lines result in different behavior at runtime.&lt;/p&gt;

&lt;p&gt;It certainly surprised me enough to make me dig deeper into the reason for the difference. I reasoned that given that the parameter values are identical at runtime, the discrepancy must happen because of a compiler operation – probably method overloading. And sure enough, the two calls resolve to different overloads.&lt;/p&gt;

&lt;p&gt;Line 7 resolves to&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; WriteLine(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; format, &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; arg0);&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;whereas Line 8 resolves to&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; WriteLine(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; format, &lt;span style="color:#0000ff;"&gt;params&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;[] arg);&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;A peek at the source code using Reflector showed that the second overload throws if arg is null, whereas the first one packs arg0 into an object array and calls the second overload.&lt;/p&gt;

&lt;p&gt;Ok, but why did the compiler pick different overloads?&lt;/p&gt;

&lt;p&gt;Intuitively, for a method call with a single parameter, you’d expect the overload resolution algorithm to choose a single parameter method over a method with variable number of arguments. And that’s what the compiler did on line 7.&lt;/p&gt;

&lt;p&gt;On line 8, the situation is different – null is directly assignable to arg0 &lt;strong&gt;and to arg&lt;/strong&gt;. The overload resolution algorithm had to choose the best function, and it chose the one with the object array.&lt;/p&gt;

&lt;p&gt;That appears counter intuitive, until you have code like&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  1: &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Test
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  2: {
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  3:     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main()
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  4:     {
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  5:         SubTest subTest = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  6:         M(subTest);
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  7:     }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  8: 
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  9:     &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; M(Test t) { Console.WriteLine(&amp;quot;&lt;span style="color:#8b0000;"&gt;Test&lt;/span&gt;&amp;quot;); }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt; 10:     &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; M(SubTest s) { Console.WriteLine(&amp;quot;&lt;span style="color:#8b0000;"&gt;SubTest&lt;/span&gt;&amp;quot;); }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt; 11: }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt; 12: 
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt; 13: &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; SubTest : Test { }&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;You wouldn’t be surprised if the call at line 6 resolved to M(SubTest), would you?&lt;/p&gt;

&lt;p&gt;The C# &lt;a href="http://msdn.microsoft.com/en-us/library/aa691339(VS.71).aspx"&gt;spec&lt;/a&gt;’s rules for determining the best match say that&lt;/p&gt;

&lt;p&gt;“ Given an implicit conversion &lt;code&gt;C1&lt;/code&gt; that converts from a type &lt;code&gt;S&lt;/code&gt; to a type &lt;code&gt;T1&lt;/code&gt;, and an implicit conversion &lt;code&gt;C2&lt;/code&gt; that converts from a type &lt;code&gt;S&lt;/code&gt; to a type &lt;code&gt;T2&lt;/code&gt;, the better conversion of the two conversions is determined as follows: &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If &lt;code&gt;T1&lt;/code&gt; and &lt;code&gt;T2&lt;/code&gt; are the same type, neither conversion is better. &lt;/li&gt;

  &lt;li&gt;If &lt;code&gt;S&lt;/code&gt; is &lt;code&gt;T1&lt;/code&gt;, &lt;code&gt;C1&lt;/code&gt; is the better conversion. &lt;/li&gt;

  &lt;li&gt;If &lt;code&gt;S&lt;/code&gt; is &lt;code&gt;T2&lt;/code&gt;, &lt;code&gt;C2&lt;/code&gt; is the better conversion. &lt;/li&gt;

  &lt;li&gt;If an implicit conversion from &lt;code&gt;T1&lt;/code&gt; to &lt;code&gt;T2&lt;/code&gt; exists, and no implicit conversion from &lt;code&gt;T2&lt;/code&gt; to &lt;code&gt;T1&lt;/code&gt; exists, &lt;code&gt;C1&lt;/code&gt; is the better conversion. &lt;/li&gt;

  &lt;li&gt;If an implicit conversion from &lt;code&gt;T2&lt;/code&gt; to &lt;code&gt;T1&lt;/code&gt; exists, and no implicit conversion from &lt;code&gt;T1&lt;/code&gt; to &lt;code&gt;T2&lt;/code&gt; exists, &lt;code&gt;C2&lt;/code&gt; is the better conversion. &lt;/li&gt;

  &lt;li&gt;… “&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this case, SubTest (T1) is implicitly convertible to Test (T2), and therefore the compiler picks M(SubTest).&lt;/p&gt;

&lt;p&gt;Now in our case, the compiler was trying to pick the best conversion between null to object and null to object[]. Applying the same rule as above, object[] is implicitly convertible to object, and therefore the overload resolution algorithm chose&amp;#160; WriteLine(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; format, &lt;span style="color:#0000ff;"&gt;params&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;[] arg). The params modifier didn’t play a part in overload resolution in this (null) case.&lt;/p&gt;

&lt;p&gt;Interesting, ain’t it?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1698685" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/senthil/archive/tags/software/default.aspx">software</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Volatile and local</title><link>http://msmvps.com/blogs/senthil/archive/2009/07/03/volatile-and-local.aspx</link><pubDate>Fri, 03 Jul 2009 05:16:54 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1697644</guid><dc:creator>Senthil</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/rsscomments.aspx?PostID=1697644</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/commentapi.aspx?PostID=1697644</wfw:comment><comments>http://msmvps.com/blogs/senthil/archive/2009/07/03/volatile-and-local.aspx#comments</comments><description>&lt;p&gt;If you’ve done any multithreading programming at all, you must be aware of the &lt;a title="http://msdn.microsoft.com/en-us/library/x13ttww7(VS.80).aspx" href="http://msdn.microsoft.com/en-us/library/x13ttww7(VS.80).aspx"&gt;volatile&lt;/a&gt; modifier. When a field is marked volatile, it tells &lt;/p&gt;  &lt;p&gt;1. the JIT compiler that it can’t hoist the field because it may be modified by multiple threads &lt;/p&gt;  &lt;p&gt;2. the CLR that the field must be read to and written from with &lt;a title="http://www.bluebytesoftware.com/blog/2008/06/13/VolatileReadsAndWritesAndTimeliness.aspx" href="http://www.bluebytesoftware.com/blog/2008/06/13/VolatileReadsAndWritesAndTimeliness.aspx"&gt;acquire and release semantics&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Given what you’ve read above, the post’s title doesn’t make sense. A local variable, by definition, cannot be accessed from multiple threads. An object referred to by a local variable can be shared among threads, but never the variable itself.&lt;/p&gt;  &lt;p&gt;Well, that was true as long as local variables remained just that – local variables. The 2.0 release of C# brought closures to the language, and C# implements capturing of local variables by making them members of a generated class. Now do you see the problem?&lt;/p&gt;  &lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  1: &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main()
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  2: {
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  3:     &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; stopRunning = false;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  4: 
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  5:     Thread t = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Thread(() =&amp;gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  6:         {
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  7:             &lt;span style="color:#0000ff;"&gt;while&lt;/span&gt; (!stopRunning)
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  8:                 Console.WriteLine(&amp;quot;&lt;span style="color:#8b0000;"&gt;Hello&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  9:         });
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt; 10:     t.Start();
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt; 11:     DoSomethingElse();
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt; 12:     stopRunning = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt; 13: }&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Nothing out of the ordinary here – I’m creating a thread, passing a lambda to the &lt;font color="#800000"&gt;Thread&lt;/font&gt; constructor, and capturing &lt;font color="#800040"&gt;stopRunning&lt;/font&gt; inside the lambda.&lt;/p&gt;

&lt;p&gt;This code isn’t correct though – for the reasons mentioned in the initial paragraph of this post, &lt;font color="#800040"&gt;stopRunning&lt;/font&gt; needs to be declared with the volatile modifier. Unfortunately, you can’t make &lt;font color="#800040"&gt;stopRunning&lt;/font&gt; volatile – the compiler complains that local variables cannot be marked volatile.&lt;/p&gt;

&lt;p&gt;Oops. &lt;/p&gt;

&lt;p&gt;Making &lt;font color="#800040"&gt;stopRunning&lt;/font&gt; a member of the class will solve the immediate problem – you can then mark the field volatile, and all is good. However, left at that, it now makes the class non-threadsafe – two threads could call &lt;font color="#800040"&gt;Main&lt;/font&gt;, and &lt;font color="#800040"&gt;stopRunning&lt;/font&gt; will be shared between them. &lt;/p&gt;

&lt;p&gt;I guess this is the price to pay for compiler magic – magic that enables seamless access to local variables from anonymous methods.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1697644" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Mutating value types – Part 1</title><link>http://msmvps.com/blogs/senthil/archive/2009/05/21/mutating-value-types-part-1.aspx</link><pubDate>Thu, 21 May 2009 05:13:48 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1692849</guid><dc:creator>Senthil</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/rsscomments.aspx?PostID=1692849</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/commentapi.aspx?PostID=1692849</wfw:comment><comments>http://msmvps.com/blogs/senthil/archive/2009/05/21/mutating-value-types-part-1.aspx#comments</comments><description>&lt;p&gt;Take a look at the following short snippet of code.&lt;/p&gt;  &lt;pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  1: &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; System;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  2: 
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  3: &lt;span style="color:#0000ff;"&gt;struct&lt;/span&gt; S
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  4: {
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  5:     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; X;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  6: }
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  7: 
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  8: &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; C
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;  9: {
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt; 10:     &lt;span style="color:#008000;"&gt;/* More code here */&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt; 11: }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt; 12: 
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt; 13: &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Test
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt; 14: {
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt; 15:     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main()
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt; 16:     {
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt; 17:         C c = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; C();
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt; 18:         c.S.X = 1;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt; 19:     }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt; 20: }&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Without knowing the type definition of C, can you tell whether the code will compile, much less work?&lt;/p&gt;

&lt;p&gt;Turns out that you can’t. It depends on whether the S in c.S is defined as a field or a property. &lt;/p&gt;
1. 

&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; C
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;{
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; S S;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;}&lt;/pre&gt;&lt;/pre&gt;
2. 

&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; C
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;{
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; S S { &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;The first type definition will compile, the second won’t (error CS1612: Cannot modify the return value of &amp;#39;C.S&amp;#39; because it is not a variable)&lt;/p&gt;

&lt;p&gt;Can you guess why?&lt;/p&gt;

&lt;p&gt;Let’s assume the compiler does allow the second type definition to compile. Would you expect the value of X in the instance of S inside C to change? That is, what would be the output of&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main()
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;{
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    C c = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; C();
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    c.S.X = 1;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    Console.WriteLine(c.S.X);
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;If you’re expecting it to be 1, then you have just broken the value semantics of a struct, S might as well have been defined as a class. The above code is logically identical to&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main()
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;{
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    C c = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; C();
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    S temp = c.S;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    temp.X = 1;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;    Console.WriteLine(c.S.X);
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px;"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Because S is a struct, the property getter always returns a copy (temp), and changing the copy will have no effect on the original instance. With c.S.X = 1, you can’t access the copy either, so the only effect of executing that statement will be to make the poor developer’s eyes go wide as he steps through the code in the debugger, wondering why a simple field assignment refuses to work. &lt;/p&gt;

&lt;p&gt;So, the C# compiler is being helpful here by not allowing this kind of code to compile.&lt;/p&gt;

&lt;p&gt;Right, so why does it compile if S is defined as a field rather than a property? We’ll see why in the next post. Meanwhile, feel free to post why you think it works.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1692849" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/senthil/archive/tags/software/default.aspx">software</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Yowza! My computer is seeing patterns!</title><link>http://msmvps.com/blogs/senthil/archive/2009/04/09/yowza-my-computer-is-seeing-patterns.aspx</link><pubDate>Thu, 09 Apr 2009 20:08:24 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1686343</guid><dc:creator>Senthil</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/rsscomments.aspx?PostID=1686343</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/commentapi.aspx?PostID=1686343</wfw:comment><comments>http://msmvps.com/blogs/senthil/archive/2009/04/09/yowza-my-computer-is-seeing-patterns.aspx#comments</comments><description>&lt;p&gt;Ever since I happened to stumble upon &lt;a href="http://www-users.cs.umn.edu/~kumar/dmbook/index.php" target="_blank"&gt;this book&lt;/a&gt; on Data Mining, I&amp;#39;ve been hooked. So much so that I&amp;#39;ve been brushing up on statistics and probability distributions just to follow along the book. &lt;/p&gt; &lt;p&gt;I&amp;#39;m currently reading the chapter on &lt;a href="http://databases.about.com/od/datamining/g/classification.htm" target="_blank"&gt;classification&lt;/a&gt; using &lt;a href="http://en.wikipedia.org/wiki/Decision_Trees" target="_blank"&gt;decision trees&lt;/a&gt;, and what appeals to me is the how the technique reduces huge sets of data (records) into simple models that can both describe the data and can predict the class of previously unseen records. If all that goes right above your head, here&amp;#39;s a simple example.&lt;/p&gt; &lt;blockquote&gt; &lt;table cellspacing="10"&gt;  &lt;tr&gt; &lt;td&gt;&lt;strong&gt;P1&lt;/strong&gt;&lt;/td&gt; &lt;td&gt;&lt;strong&gt;P2&lt;/strong&gt;&lt;/td&gt; &lt;td&gt;&lt;strong&gt;Class (Result)&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;True&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;False&lt;/td&gt; &lt;td&gt;False&lt;/td&gt; &lt;td&gt;False&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;False&lt;/td&gt; &lt;td&gt;False&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;False&lt;/td&gt; &lt;td&gt;True&lt;/td&gt; &lt;td&gt;False&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; &lt;p&gt;Given the above tabular values, can the computer figure out that it is the truth table for P1 ^ P2 (with ^ representing &lt;a href="http://en.wikipedia.org/wiki/Logical_conjunction" target="_blank"&gt;logical conjunction&lt;/a&gt;, not XOR) ? If it can, it has &lt;/p&gt; &lt;p&gt;1. A model that describes the data, i.e., the data is the conjunction of the two boolean variables.&lt;/p&gt; &lt;p&gt;2. An evaluator that can calculate the result, given P1 and P2, i.e., predict the class. Since all combination of values are already available, there are no unseen records in this case.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;A decision tree for the above table looks like this visually :-&lt;/p&gt; &lt;p&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/senthil/image_5F00_4.png"&gt;&lt;img height="202" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/senthil/image_5F00_thumb.png" width="213" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;with green edges and red edges representing true and false values for the attribute represented by the node, respectively. As you can see, the non-leaf nodes each represent an attribute, with one edge for each possible value of that attribute. The leaf nodes represent the result (class). Since we are dealing with binary attributes, the decision tree turns out to be a binary tree. Note that you can find out the result of { P1 = True, P2 = True } by simply navigating the tree and reading the value of the leaf node ( green edge from P1 to P2, green edge from P2 to T, and then read the value, T = true).&lt;/p&gt; &lt;p&gt;This was so interesting that I actually wrote a generic decision tree builder in C# (&lt;a href="http://cid-1db38b528599dd02.skydrive.live.com/self.aspx/.Public" target="_blank"&gt;download&lt;/a&gt;). It uses &lt;a href="http://www.google.co.in/search?q=Hunt%27s+Algorithm&amp;amp;ie=utf-8&amp;amp;oe=utf-8&amp;amp;aq=t&amp;amp;rls=org.mozilla:en-US:official&amp;amp;client=firefox-a" target="_blank"&gt;Hunt&amp;#39;s Algorithm&lt;/a&gt; to build the decision tree and uses Entropy as the measure to select attributes. At the moment, it can work only on records with nominal attributes (attributes like enums whose values are limited to a finite set). After training, it returns a decision tree, which can then be exported to XML or can be used to predict classes for new records. &lt;/p&gt; &lt;p&gt;Enough of the theory, let&amp;#39;s see it in action. Here&amp;#39;s how code that uses my tree builder looks.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;TruthTableEntry &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;Record&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;bool&lt;/span&gt;&amp;gt;
{
    &lt;span style="color:blue;"&gt;public bool &lt;/span&gt;P1 { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }
    &lt;span style="color:blue;"&gt;public bool &lt;/span&gt;P2 { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public override bool &lt;/span&gt;Equals(&lt;span style="color:blue;"&gt;object &lt;/span&gt;obj)
    {
        &lt;span style="color:blue;"&gt;var &lt;/span&gt;other = obj &lt;span style="color:blue;"&gt;as &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;TruthTableEntry&lt;/span&gt;;
        &lt;span style="color:blue;"&gt;if &lt;/span&gt;(other == &lt;span style="color:blue;"&gt;null&lt;/span&gt;)
            &lt;span style="color:blue;"&gt;return false&lt;/span&gt;;

        &lt;span style="color:blue;"&gt;return &lt;/span&gt;other.P1 == &lt;span style="color:blue;"&gt;this&lt;/span&gt;.P1 &amp;amp;&amp;amp; other.P2 == &lt;span style="color:blue;"&gt;this&lt;/span&gt;.P2;
    }

    &lt;span style="color:blue;"&gt;public override int &lt;/span&gt;GetHashCode()
    {
        &lt;span style="color:blue;"&gt;return &lt;/span&gt;P1.GetHashCode() ^ P2.GetHashCode();
    }
}&lt;/pre&gt;&lt;pre class="code"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;static void &lt;/span&gt;Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)
{
&lt;span style="color:#2b91af;"&gt;   TruthTableEntry&lt;/span&gt;[] table = 
   {
       &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;TruthTableEntry&lt;/span&gt;() { P1 = &lt;span style="color:blue;"&gt;true&lt;/span&gt;, P2 = &lt;span style="color:blue;"&gt;true&lt;/span&gt;, Class = &lt;span style="color:blue;"&gt;true &lt;/span&gt;},
       &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;TruthTableEntry&lt;/span&gt;() { P1 = &lt;span style="color:blue;"&gt;true&lt;/span&gt;, P2 = &lt;span style="color:blue;"&gt;false&lt;/span&gt;, Class = &lt;span style="color:blue;"&gt;false&lt;/span&gt;},
       &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;TruthTableEntry&lt;/span&gt;() { P1 = &lt;span style="color:blue;"&gt;false&lt;/span&gt;, P2 = &lt;span style="color:blue;"&gt;true&lt;/span&gt;, Class = &lt;span style="color:blue;"&gt;false&lt;/span&gt;},
       &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;TruthTableEntry&lt;/span&gt;() { P1 = &lt;span style="color:blue;"&gt;false&lt;/span&gt;, P2 = &lt;span style="color:blue;"&gt;false&lt;/span&gt;, Class = &lt;span style="color:blue;"&gt;false &lt;/span&gt;}
   };

   &lt;span style="color:blue;"&gt;var &lt;/span&gt;tree = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;TreeBuilder&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;TruthTableEntry&lt;/span&gt;, &lt;span style="color:blue;"&gt;bool&lt;/span&gt;&amp;gt;().Train(table);
   &lt;span style="color:blue;"&gt;string &lt;/span&gt;predicate = FormPredicate(tree.RootNode, &lt;span style="color:#a31515;"&gt;&amp;quot;&amp;quot;&lt;/span&gt;);
   &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(predicate);
}&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;The TruthTableEntry class represents a row in the truth table above, and an array of those records are given to the TreeBuilder instance&amp;#39;s Train method. The decision tree returned by it is then translated into a predicate by the FormPredicate method. Here&amp;#39;s how the tree looks in XML if you call Save on the tree.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color:#a31515;"&gt;xml &lt;/span&gt;&lt;span style="color:red;"&gt;version&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;1.0&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;encoding&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;utf-8&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;?&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Node &lt;/span&gt;&lt;span style="color:red;"&gt;ParentConditionValue&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&amp;quot; &lt;span style="color:red;"&gt;SplitAttribute&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;P1&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Node &lt;/span&gt;&lt;span style="color:red;"&gt;ParentConditionValue&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;True&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;SplitAttribute&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;P2&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Node &lt;/span&gt;&lt;span style="color:red;"&gt;ParentConditionValue&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;True&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;Class&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;True&lt;/span&gt;&amp;quot; &lt;span style="color:blue;"&gt;/&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Node &lt;/span&gt;&lt;span style="color:red;"&gt;ParentConditionValue&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;False&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;Class&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;False&lt;/span&gt;&amp;quot; &lt;span style="color:blue;"&gt;/&amp;gt;
  &amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Node&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Node &lt;/span&gt;&lt;span style="color:red;"&gt;ParentConditionValue&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;False&lt;/span&gt;&amp;quot; &lt;span style="color:red;"&gt;Class&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color:blue;"&gt;False&lt;/span&gt;&amp;quot; &lt;span style="color:blue;"&gt;/&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;Node&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;which exactly matches what we expected.&lt;/p&gt;
&lt;p&gt;&lt;span style="color:blue;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:blue;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre class="code"&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/senthil/image_5F00_10.png"&gt;&lt;img height="202" alt="image" src="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/senthil/image_5F00_thumb_5F00_1.png" width="213" border="0" /&gt;&lt;/a&gt; &lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The FormPredicate method attempts to transform the tree into a predicate clause, as expressed mathematically in predicate logic. For the above tree, it returns&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;(P1 ^ P2) v (~P1 ^ False)&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;which when reduced through the laws of predicate logic&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;(P1 ^ P2) v (~P1 ^ False) &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;= &lt;font face="Courier New"&gt;(P1 ^ P2) v False (since False ^ P == False)&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;= (P1 ^ P2)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (since False v P == P)&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;And there you have it, the computer figured it out correctly. Yowza :)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1686343" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/senthil/archive/tags/software+tools/default.aspx">software tools</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/software/default.aspx">software</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/Data+Mining/default.aspx">Data Mining</category></item><item><title>Confusion++</title><link>http://msmvps.com/blogs/senthil/archive/2009/02/26/confusion.aspx</link><pubDate>Thu, 26 Feb 2009 13:09:44 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1674077</guid><dc:creator>Senthil</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/rsscomments.aspx?PostID=1674077</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/commentapi.aspx?PostID=1674077</wfw:comment><comments>http://msmvps.com/blogs/senthil/archive/2009/02/26/confusion.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ll bet a hundred bucks that any entry level C++ interview or exam will somehow drift into questions about the pre and post increment operators. It&amp;#39;s almost become a canonical, rite of passage sort of thing.&lt;/p&gt; &lt;p&gt;Now using the operators is one thing, overloading them for your own types is another. In C++, you write something like&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;class &lt;/span&gt;X {
    &lt;span style="color:blue;"&gt;int &lt;/span&gt;val;
&lt;span style="color:blue;"&gt;public&lt;/span&gt;:

    X() : val(0){ }

    X &lt;span style="color:blue;"&gt;operator&lt;/span&gt;++() { val++; &lt;span style="color:blue;"&gt;return &lt;/span&gt;*&lt;span style="color:blue;"&gt;this&lt;/span&gt;; }
    X &lt;span style="color:blue;"&gt;operator&lt;/span&gt;++(&lt;span style="color:blue;"&gt;int&lt;/span&gt;) { X pX = *&lt;span style="color:blue;"&gt;this&lt;/span&gt;; val++; &lt;span style="color:blue;"&gt;return &lt;/span&gt;pX; };

    &lt;span style="color:blue;"&gt;int &lt;/span&gt;Value() { &lt;span style="color:blue;"&gt;return &lt;/span&gt;val; }
};&lt;/pre&gt;
&lt;p&gt;Fairly straightforward stuff - C++ uses the int overload to distinguish between pre and post, and the post increment overload copies itself before incrementing and returns the copy.&lt;/p&gt;
&lt;p&gt;Now let&amp;#39;s see how to do this in C#.&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;X
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public int &lt;/span&gt;Value { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }

    &lt;span style="color:blue;"&gt;public static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;X &lt;/span&gt;&lt;span style="color:blue;"&gt;operator &lt;/span&gt;++(&lt;span style="color:#2b91af;"&gt;X &lt;/span&gt;p)
    {
        &lt;span style="color:blue;"&gt;int &lt;/span&gt;x = p.Value;
        &lt;span style="color:blue;"&gt;return new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;X&lt;/span&gt;() { Value = x + 1 };
    }
}&lt;/pre&gt;
&lt;p&gt;No, there&amp;#39;s no separate overload for the other one - the same method works for both pre and post increment operations. The compiler does the work of generating code that exhibits correct pre and post increment behavior. For code like&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;span style="color:#2b91af;"&gt;X &lt;/span&gt;x = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;X&lt;/span&gt;();&lt;br /&gt;&lt;span style="color:#2b91af;"&gt;X &lt;/span&gt;y = x++;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;it generates&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:#2b91af;"&gt;X &lt;/span&gt;x = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;X&lt;/span&gt;();
&lt;span style="color:#2b91af;"&gt;X &lt;/span&gt;y = x;
x = &lt;span style="color:#2b91af;"&gt;X&lt;/span&gt;.op_Increment(x);&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;and for code like&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;span style="color:#2b91af;"&gt;X &lt;/span&gt;x = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;X&lt;/span&gt;();&lt;br /&gt;&lt;span style="color:#2b91af;"&gt;X &lt;/span&gt;y = ++x;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;it generates&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color:#2b91af;"&gt;X &lt;/span&gt;x = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;X&lt;/span&gt;();
&lt;span style="color:#2b91af;"&gt;X &lt;/span&gt;y = x = &lt;span style="color:#2b91af;"&gt;X&lt;/span&gt;.op_Increment(x);&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;Nifty, eh?&lt;/p&gt;
&lt;p&gt;But wait, did you notice the difference between the C++ and C# overload implementation? The C# overload does not modify the original at all and always returns a copy, whereas the C++ code always modifies the current instance and returns a copy only for the post increment overload. Looking at the generated code, it should be easy to understand why - the compiler can&amp;#39;t do its magic if the overload tinkers with the original instance.&lt;/p&gt;
&lt;p&gt;Did you notice that X is a reference type?&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;span style="color:#2b91af;"&gt;X &lt;/span&gt;x = &lt;span style="color:blue;"&gt;new&lt;/span&gt;&lt;span style="color:#2b91af;"&gt;X&lt;/span&gt;();&lt;br /&gt;&lt;span style="color:#2b91af;"&gt;X&lt;/span&gt;y = x;&lt;br /&gt;&lt;br /&gt;x++;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Given that x and y are referring to the same object after executing the second line, shouldn&amp;#39;t the increment be visible from y as well? It doesn&amp;#39;t happen though, because the overload returns a new instance that then gets assigned to x, leaving y referring to the &amp;quot;old&amp;quot; unmodified instance.&lt;/p&gt;
&lt;p&gt;All this confusion will not arise if X is a value type. The assignment of x to y will create a copy, so there&amp;#39;s no possibility of changes in x reflecting in y. And modifying the passed instance from within the operator overload will have no effect on the original instance either.&lt;/p&gt;
&lt;p&gt; Moral of the story : watch out when overloading operators on reference types.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1674077" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/senthil/archive/tags/software+C_2300_+language/default.aspx">software C# language</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Not all IEnumerable&lt;T&gt; are equal</title><link>http://msmvps.com/blogs/senthil/archive/2008/09/04/not-all-ienumerable-lt-t-gt-are-equal.aspx</link><pubDate>Thu, 04 Sep 2008 19:25:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1646798</guid><dc:creator>Senthil</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/rsscomments.aspx?PostID=1646798</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/commentapi.aspx?PostID=1646798</wfw:comment><comments>http://msmvps.com/blogs/senthil/archive/2008/09/04/not-all-ienumerable-lt-t-gt-are-equal.aspx#comments</comments><description>&lt;p&gt;Implementing IEnumerable&amp;lt;T&amp;gt; can turn out to be tricky in certain cases. Consider the following code snippet&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;namespace &lt;/span&gt;Test&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:blue;"&gt;class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Program&lt;br /&gt;    &lt;/span&gt;{&lt;br /&gt;        &lt;span style="color:blue;"&gt;static void &lt;/span&gt;Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;        {&lt;br /&gt;            Consume(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;string&lt;/span&gt;&amp;gt;() { &lt;span style="color:#a31515;"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;quot;b&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;quot;c&amp;quot; &lt;/span&gt;});&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:blue;"&gt;static void &lt;/span&gt;Consume&amp;lt;T&amp;gt;(&lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;T&amp;gt; stream)&lt;br /&gt;        {&lt;br /&gt;            T t1 = stream.First();&lt;br /&gt;            T t2 = stream.First();&lt;br /&gt;&lt;br /&gt;            &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(t1.Equals(t2));&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As you&amp;#39;d expect, it prints true. Each First() call results in a call to stream.GetEnumerator(), and each such enumerator returns elements from the beginning of the list, so calling First() twice returns the same (first) element. All good so far.&lt;/p&gt;
&lt;p&gt;Here&amp;#39;s a tiny class.&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;        class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;StringGenerator&lt;br /&gt;        &lt;/span&gt;{&lt;br /&gt;            &lt;span style="color:blue;"&gt;int &lt;/span&gt;index;&lt;br /&gt;&lt;br /&gt;            &lt;span style="color:blue;"&gt;public string &lt;/span&gt;GetNext()&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color:blue;"&gt;return &lt;/span&gt;(index++).ToString();&lt;br /&gt;            }&lt;br /&gt;        }&lt;/pre&gt;
&lt;p&gt;As you can see, it generates whole numbers as strings. Not very convenient to use though, wouldn&amp;#39;t it be great if we can wrap it and make it enumerable?&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;        static &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;string&lt;/span&gt;&amp;gt; ConvertToEnumerable(&lt;span style="color:#2b91af;"&gt;StringGenerator &lt;/span&gt;g)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:blue;"&gt;string &lt;/span&gt;item = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;            &lt;span style="color:blue;"&gt;while &lt;/span&gt;((item = g.GetNext()) != &lt;span style="color:blue;"&gt;null&lt;/span&gt;)&lt;br /&gt;                &lt;span style="color:blue;"&gt;yield return &lt;/span&gt;item;&lt;br /&gt;        }&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ConvertToEnumerable simply loops over the list of items generated and makes use of yield return to make it enumerable.&lt;/p&gt;
&lt;p&gt;Great, now what does &lt;/p&gt;
&lt;pre class="code"&gt;        Consume(ConvertToEnumerable(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;StringGenerator&lt;/span&gt;()));&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;print?&lt;/p&gt;
&lt;p&gt;It prints false. &lt;/p&gt;
&lt;p&gt;False? FALSE? Can you figure out the reason?&lt;/p&gt;
&lt;p&gt;If you&amp;#39;ve read &lt;a href="http://blogs.msdn.com/oldnewthing/archive/2008/08/12/8849519.aspx"&gt;Raymond&amp;#39;s&lt;/a&gt; posts on implementation of iterators, you should have figured it out by now. The crux of the problem is that all enumerators returned share the same instance of StringGenerator.&amp;nbsp; Calling First() twice results in two calls to GetNext() on the same StringGenerator instance, and the values returned will obviously be different. To verify that, try creating the StringGenerator instance inside the ConvertToEnumerable function - it will print true now.&lt;/p&gt;
&lt;p&gt;This bit me when I wrote code that parsed stuff out of an IEnumerable&amp;lt;string&amp;gt; instance. The actual program read text from a file, so I had a ConvertToEnumerable routine just like the one above, except that it took TextReader as the parameter. The Consume method passed the constructed IEnumerable&amp;lt;T&amp;gt; instance to various methods (say Method1 and Method2), with the assumption that whatever Method1 read off the stream won&amp;#39;t be read again by Method2. &lt;/p&gt;
&lt;p&gt;As we saw just now, this works if Consume is passed an IEnumerable&amp;lt;T&amp;gt; constructed like the StringGenerator case. It fails badly if a List&amp;lt;string&amp;gt; is passed instead. Because I wanted the &amp;quot;read elements off the stream&amp;quot; behavior, I called GetEnumerator() once for the passed IEnumerable&amp;lt;T&amp;gt; and then changed the methods called by Consume to take that IEnumerator&amp;lt;T&amp;gt; instead of IEnumerable&amp;lt;T&amp;gt;. That made the code work correctly for both cases.&lt;/p&gt;
&lt;p&gt;Moral : Make sure you understand the implications when yield returning items off a shared item source.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1646798" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/senthil/archive/tags/software+C_2300_+language/default.aspx">software C# language</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category></item><item><title>Itertools for C# - Tee</title><link>http://msmvps.com/blogs/senthil/archive/2008/05/05/itertools-for-c-tee.aspx</link><pubDate>Mon, 05 May 2008 17:03:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1614250</guid><dc:creator>Senthil</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/rsscomments.aspx?PostID=1614250</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/commentapi.aspx?PostID=1614250</wfw:comment><comments>http://msmvps.com/blogs/senthil/archive/2008/05/05/itertools-for-c-tee.aspx#comments</comments><description>&lt;p&gt;Tee is a cool function that &amp;quot;clones&amp;quot; enumerators whatever their current state is - it basically allows you to branch off an enumerator into as many enumerators as you want, all independent of each other.&lt;/p&gt;&lt;p&gt;&amp;nbsp;You can do something like&lt;/p&gt;
&lt;pre&gt;List&amp;lt;int&amp;gt; list = new List&amp;lt;int&amp;gt; { 1, 2, 3, 4, 5 };&lt;br /&gt;&lt;br /&gt;IEnumerator&amp;lt;int&amp;gt; iterable1 = list.GetEnumerator();&lt;br /&gt;&lt;br /&gt;IEnumerator&amp;lt;int&amp;gt; []teedIterables = Itertools.Tee(iterable1, 2);&lt;br /&gt;&lt;br /&gt;foreach(int val in teedIterables[0])&lt;br /&gt;{&lt;br /&gt;   Console.WriteLine(val);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;foreach(int val in teedIterables[1])&lt;br /&gt;{&lt;br /&gt;   Console.WriteLine(val);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// prints 1 2 3 4 5 1 2 3 4 5&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;
If there was a iterable1.MoveNext() before the call to Tee, then the output would have been 2 3 4 5 2 3 4 5.

The implementation proved to be pretty interesting - and complicated, partly because the C# compiler does not allow the yield statement inside anonymous methods. Here&amp;#39;s the implementation.
&lt;/p&gt;
&lt;pre&gt;public static IEnumerator&amp;lt;T&amp;gt;[] Tee&amp;lt;T&amp;gt;(IEnumerator&amp;lt;T&amp;gt; source, int count)&lt;br /&gt;{&lt;br /&gt;    List&amp;lt;T&amp;gt; tValues = new List&amp;lt;T&amp;gt;();&lt;br /&gt;    IEnumerator&amp;lt;T&amp;gt;[] results = new IEnumerator&amp;lt;T&amp;gt;[count];&lt;br /&gt;&lt;br /&gt;    for (int i = 0; i &amp;lt; count; ++i)&lt;br /&gt;    {&lt;br /&gt;       int currentLocation = 0;&lt;br /&gt;       results [ i ] = CreateEnumerator(source, new EnumeratorState&amp;lt;T&amp;gt;() { CurrentLocation = currentLocation, TValues = tValues });&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return results;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private static IEnumerator&amp;lt;T&amp;gt; CreateEnumerator&amp;lt;T&amp;gt;(IEnumerator&amp;lt;T&amp;gt; source, EnumeratorState&amp;lt;T&amp;gt; state)&lt;br /&gt;{&lt;br /&gt;   while (true)&lt;br /&gt;   {&lt;br /&gt;      if (state.CurrentLocation &amp;lt; state.TValues.Count)&lt;br /&gt;      {&lt;br /&gt;          yield return state.TValues[state.CurrentLocation++];&lt;br /&gt;      }&lt;br /&gt;      else&lt;br /&gt;      {&lt;br /&gt;         if (source.MoveNext())&lt;br /&gt;         {&lt;br /&gt;            state.TValues.Add(source.Current);&lt;br /&gt;            state.CurrentLocation = state.TValues.Count;&lt;br /&gt;            yield return source.Current;&lt;br /&gt;         }&lt;br /&gt;         else&lt;br /&gt;         {&lt;br /&gt;             break;&lt;br /&gt;         }&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class EnumeratorState&amp;lt;T&amp;gt;&lt;br /&gt;{&lt;br /&gt;   internal int CurrentLocation { get; set; }&lt;br /&gt;   internal List&amp;lt;T&amp;gt; TValues { get; set; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;There&amp;#39;s a fair bit of code involved, as you can see. The basic idea behind the implementation is to maintain a list as a backing store. Each teed off enumerator attempts to read from the list - if it hits the end of the list, it advances the original enumerator&amp;nbsp; and gets the current value, updates the list and returns that value. The rest of the code is plumbing to work around the inability to use yield inside an anonymous method. The code basically does what the compiler would have done - there&amp;#39;s the EnumeratorState class to hold captured variables and a new instance of the class is created and passed to CreateEnumerator, which is in the place of the anonymous method.&lt;/p&gt;&lt;p&gt;Tee is that kind of function that is incredibly useful once you know you can do such a thing. Let&amp;#39;s say you have an application that needs to process lines in a file, but the processing can happen in different contexts, independent of each other. Take for example, a log parser, that goes through each line in a file, looking for the start of an operation. The log parser notifies another component once it finds the start of the operation and proceeds through the file looking for the next operation. Normally, you&amp;#39;ll solve the problem by adding the component to a list that gets notified after the parser reads each line. With Tee, you can simply tee off an enumerator and pass it to the other component - both the log parser and the component now have independent enumerators and can actually run in parallel. And you can tee off as many enumerators as there are components. &lt;/p&gt;&lt;p&gt;With that, we come to the end of this series of blog posts on implementing itertools in C#. The source code for all the functions implemented in the series is available at &lt;a href="http://code.msdn.microsoft.com/itertools"&gt;http://code.msdn.microsoft.com/itertools&lt;/a&gt;.&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1614250" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/senthil/archive/tags/software/default.aspx">software</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/software+C_2300_+language/default.aspx">software C# language</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category></item><item><title>C# 3.0 compiler bug - Using object initializers, generics and value types</title><link>http://msmvps.com/blogs/senthil/archive/2007/12/26/c-3-0-compiler-bug-using-object-initializers-generics-and-value-types.aspx</link><pubDate>Wed, 26 Dec 2007 17:44:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1420645</guid><dc:creator>Senthil</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/rsscomments.aspx?PostID=1420645</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/commentapi.aspx?PostID=1420645</wfw:comment><comments>http://msmvps.com/blogs/senthil/archive/2007/12/26/c-3-0-compiler-bug-using-object-initializers-generics-and-value-types.aspx#comments</comments><description>&lt;p&gt;There is a description of the bug &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=319430"&gt;here&lt;/a&gt;. The following piece of code demonstrates the bug.&lt;/p&gt;
&lt;pre&gt;    class Program
    {
        interface I
        {
            int X { get; set; }
        }

        struct S : I
        {
            public int X { get; set; }
        }

        static void Main(string[] args)
        {
            Func&amp;lt;S&amp;gt;();
        }

        static void Func&amp;lt;T&amp;gt;() where T : I, new()
        {
            var c = new T() { X = 1 };
            Console.WriteLine(c.X);
        }
    }
&lt;/pre&gt;&lt;p&gt;The code prints 0 instead of 1. The bug goes away if object initializers are not used - changing var c = new T() { X = 1 }; to var c = new T(); c.X = 1; will print 1.&lt;/p&gt;&lt;p&gt;I had assumed all along that object initializers were transformed into property setters at the source code level (or somewhere above IL). This bug doesn&amp;#39;t help much to confirm that :)&lt;/p&gt;&lt;p&gt;Anyway, let&amp;#39;s see what&amp;#39;s causing the problem. Peeking into the generated IL,&amp;nbsp;&lt;/p&gt;
&lt;pre&gt;   .locals init (
        [0] !!T c,
        [1] !!T &amp;lt;&amp;gt;g__initLocal0,
        [2] !!T CS$0$0000)
        ... // Store zeroed out instance of S in locals[1]
    L_0022: ldloc.1 
    L_0023: box !!T
    L_0028: ldc.i4.1 
    L_0029: callvirt instance void CSharp3Test.Program/I::set_X(int32)
    L_002e: nop 
    L_002f: ldloc.1 
    L_0030: stloc.0 
    L_0031: ldloca.s c
    L_0033: constrained !!T
    L_0039: callvirt instance int32 CSharp3Test.Program/I::get_X()
    L_003e: call void [mscorlib]System.Console::WriteLine(int32)
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;Can you spot the problem now?&lt;/p&gt;&lt;p&gt;You can see that at L_0023, S is boxed and the boxed instance is used to make the virtual call to set X. You can also see that the boxed instance is not stored in any of the local variables, the &lt;b&gt;callvirt&lt;/b&gt; instruction pops it off the stack and then it&amp;#39;s gone. To load the value of X, the &lt;b&gt;callvirt&lt;/b&gt; instruction is given a reference to c (locals[0]), which contains the unboxed instance of the struct. Which is why we are getting a 0 (the default value), instead of 1. Essentially, the compiler is generating the equivalent IL for something like&amp;nbsp;&lt;/p&gt;
&lt;pre&gt;   S s = new S();
   I i = s;
   i.X = 10;
   Console.WriteLine(s.X);
&lt;/pre&gt;&lt;p&gt;This again prints 0 instead of 10, because i is assigned a different (boxed) instance of S and therefore changing i.X doesn&amp;#39;t change s.X.&lt;br /&gt;&lt;/p&gt;But then how does doing the initialization in two steps (var c = new T(); c.X = 1) work. The answer - Two step initialization does not use boxing when setting the value of X. Here&amp;#39;s how the generated IL looks.&lt;br /&gt;
&lt;pre&gt;   .locals init (
        [0] !!T c,
        [1] !!T CS$0$0000)
    L_0021: stloc.0 
    L_0022: ldloca.s c
    L_0024: ldc.i4.1 
    L_0025: constrained !!T
    L_002b: callvirt instance void CSharp3Test.Program/I::set_X(int32)
    L_0030: nop 
    L_0031: ldloca.s c
    L_0033: constrained !!T
    L_0039: callvirt instance int32 CSharp3Test.Program/I::get_X()
    L_003e: call void [mscorlib]System.Console::WriteLine(int32)
&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;The box instruction is gone, instead, the compiler has generated a constrained prefix for the &lt;b&gt;callvirt&lt;/b&gt; instruction. MSDN says that&lt;/p&gt;&lt;p&gt;&amp;quot;When a &lt;span class="keyword"&gt;callvirt&lt;/span&gt; &lt;span class="parameter"&gt;method&lt;/span&gt; instruction has been prefixed by &lt;span class="keyword"&gt;constrained&lt;/span&gt; &amp;nbsp;&lt;span class="parameter"&gt;thisType&lt;/span&gt;, the instruction is executed as follows: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;If &lt;span class="parameter"&gt;thisType&lt;/span&gt; is a reference type (as opposed to a value type) then &lt;span class="parameter"&gt;ptr&lt;/span&gt; is dereferenced and passed as the &amp;#39;this&amp;#39; pointer to the &lt;span class="keyword"&gt;callvirt&lt;/span&gt; of &lt;span class="parameter"&gt;method&lt;/span&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;If &lt;span class="parameter"&gt;thisType&lt;/span&gt; is a value type and &lt;span class="parameter"&gt;thisType&lt;/span&gt; implements &lt;span class="parameter"&gt;method&lt;/span&gt; then &lt;span class="parameter"&gt;ptr&lt;/span&gt; is passed unmodified as the &amp;#39;this&amp;#39; pointer to a &lt;span class="keyword"&gt;call&lt;/span&gt; &amp;nbsp;&lt;span class="parameter"&gt;method&lt;/span&gt; instruction, for the implementation of &lt;span class="parameter"&gt;method&lt;/span&gt; by &lt;span class="parameter"&gt;thisType&lt;/span&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;...&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&amp;quot;&lt;/p&gt;&lt;p&gt;In other words, the address of the instance is passed as the this parameter to the &lt;b&gt;call &lt;/b&gt;method - no boxing at all. If you&amp;#39;d looked carefully enough, the getter for X uses the constrained prefix, even in our buggy IL (the first listing). &lt;br /&gt;&lt;/p&gt;&lt;p&gt;That explains the bug then, but opens up another question. If virtual dispatch can be done for a value type without boxing, then why not do it that way for&lt;/p&gt;&lt;pre&gt;   S s = new S();&lt;br /&gt;   I i = s;&lt;br /&gt;   i.X = 10;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&amp;nbsp;as well? Mind you, virtual dispatch doesn&amp;#39;t mean anything for value types, as they cannot derive from or derived by anything else, so any &lt;b&gt;callvirt&lt;/b&gt; instruction on value types can be treated as a straight &lt;b&gt;call&lt;/b&gt; instruction. The constrained prefix does exactly this, after making sure that &lt;b&gt;this &lt;/b&gt;is a value type. So why not use it for all virtual calls? Performance (not many value types implementing interfaces)? &lt;/p&gt;&lt;p&gt;What do you think?&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1420645" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/senthil/archive/tags/software+C_2300_+language/default.aspx">software C# language</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category></item><item><title>Type inference != Dynamic typing</title><link>http://msmvps.com/blogs/senthil/archive/2007/11/19/type-inference-dynamic-typing.aspx</link><pubDate>Mon, 19 Nov 2007 16:27:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1335878</guid><dc:creator>Senthil</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/rsscomments.aspx?PostID=1335878</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/senthil/commentapi.aspx?PostID=1335878</wfw:comment><comments>http://msmvps.com/blogs/senthil/archive/2007/11/19/type-inference-dynamic-typing.aspx#comments</comments><description>&lt;p&gt;Local variable type inferencing is a new feature in C# 3.5 - a very &amp;quot;handy&amp;quot; one, in that it saves a lot of typing. Basically, it lets you do&amp;nbsp;&lt;/p&gt;&lt;pre&gt;var dict = new Dictionary&amp;lt;string, List&amp;lt;int, Dictionary&amp;lt;int, string&amp;gt;&amp;gt;&amp;gt;();&lt;/pre&gt;&lt;p&gt;instead of&amp;nbsp;&lt;/p&gt;&lt;pre&gt;Dictionary&amp;lt;string, List&amp;lt;int, Dictionary&amp;lt;int, string&amp;gt;&amp;gt;&amp;gt; dict = Dictionary&amp;lt;string, List&amp;lt;int, Dictionary&amp;lt;int, string&amp;gt;&amp;gt;&amp;gt;();&lt;/pre&gt;&lt;p&gt;That&amp;#39;s pretty cool, but remember, C# is still a statically typed language. dict is statically bound to the type Dictionary&amp;lt;string, List&amp;lt;int, Dictionary&amp;lt;int, string&amp;gt;&amp;gt;&amp;gt; and you cannot change it. You cannot do&lt;/p&gt;&lt;pre&gt;dict = Dictionary&amp;lt;int, string&amp;gt;();&lt;/pre&gt;&lt;p&gt;in the same method. The compiler will complain that the type on the RHS is not convertible to the statically bound type of dict. &lt;/p&gt;&lt;p&gt;Contrast this to a dynamically typed language like Javascript, which also uses the var keyword to declare variables.&amp;nbsp;&lt;/p&gt;&lt;pre&gt;var x = 1;&lt;p&gt;x = new Array();&lt;/p&gt;&lt;p&gt;x = &amp;quot;23&amp;quot;;&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;Or to Python&amp;nbsp;&lt;/p&gt;&lt;pre&gt;x = 42&lt;p&gt;x = def fn(z) : return z + 1&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;In such languages, variables (x, in our example) simply act as placeholders and get bound to the type of the value they are holding at the moment. In the first example, x is holding an integer after executing the first line. After executing the second line, it&amp;#39;s holding an array. If the same two lines of code were to be written in a statically typed language, the second line would be correct only if an array is somehow convertible to an int.&lt;/p&gt;&lt;p&gt;The point of the post - don&amp;#39;t be misled by the var keyword. The variable it declares is still a good old statically typed variable. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1335878" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/senthil/archive/tags/software/default.aspx">software</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/software+C_2300_+language/default.aspx">software C# language</category><category domain="http://msmvps.com/blogs/senthil/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category></item></channel></rss>