<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Luca Bolognese's WebLog : C# Programming</title><link>http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx</link><description>Tags: C# Programming</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>My PDC session is online - “Future directions for C# and Visual Basic”</title><link>http://blogs.msdn.com/lucabol/archive/2009/11/23/my-pdc-session-is-online-future-directions-for-c-and-visual-basic.aspx</link><pubDate>Mon, 23 Nov 2009 21:17:44 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9927546</guid><dc:creator>lucabol</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/9927546.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=9927546</wfw:commentRss><description>&lt;p&gt;In case you are training to play the part of a first generation Italian immigrant in a Broadway show or if you want to understand why I never short msft stock: &lt;a title="http://microsoftpdc.com/Sessions/FT11" href="http://microsoftpdc.com/Sessions/FT11"&gt;http://microsoftpdc.com/Sessions/FT11&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9927546" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/.NET+Futures/default.aspx">.NET Futures</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/VB/default.aspx">VB</category></item><item><title>Luca at PDC 2009 next week</title><link>http://blogs.msdn.com/lucabol/archive/2009/11/13/luca-at-pdc-2009-next-week.aspx</link><pubDate>Fri, 13 Nov 2009 18:49:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9922139</guid><dc:creator>lucabol</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/9922139.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=9922139</wfw:commentRss><description>&lt;p&gt;I’ll be in Los Angeles next week for PDC 2009. My session is called “&lt;a href="http://microsoftpdc.com/Sessions/FT11"&gt;Future Directions for C# and Visual Basic&lt;/a&gt;” and it comes on Tuesday immediately after the first keynote.&lt;/p&gt;  &lt;p&gt;I’m planning on spending the first half of the session talking about the biggest trends influencing C# and VB. The second part will be about more future looking features we are playing with these days.&lt;/p&gt;  &lt;p&gt;My deck has just two slides, as always. It’s all about watching me typing code on stage, hoping that I make crazy errors …&lt;/p&gt;  &lt;p&gt;There are several other interesting language related sessions at PDC. Here is a list of them (please notice that the times might change). Also feel free to drop by the languages booth and chat. My team and I will be there most of the time.&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;&lt;b&gt;Day&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;&lt;b&gt;Time&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Title&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;&lt;b&gt;Presenter&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;&lt;b&gt;Room&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Tues 11/17&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;11:00 - 12:00&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Future Directions for C# and Visual Basic&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Luca Bolognese&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;Hall F&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Tues 11/17&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;11:00 - 12:00&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Accelerated Windows Application Development with Microsoft Visual C++ 2010&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Boris Jabes&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;408B&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Tues 11/17&lt;b&gt;&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;12:30 - 13:15&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Dynamic Binding in C# 4&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Mads Torgersen&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;Hall F&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Tues 11/17&lt;b&gt;&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;12:30 - 13:15&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Using Dynamic Languages to Build Scriptable Applications&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Dino Viehland&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;403AB&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Tues 11/17&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;13:30 - 14:30&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;C++ Forever: Interactive Applications in the Age of Manycore&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Rick Molloy&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;515B&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Tues 11/17&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;16:30 - 17:30&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Manycore and the Microsoft .NET Framework 4: A Match Made in Microsoft Visual Studio 2010&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Stephen Toub&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;502A&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Tues 11/17&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;16:30 - 17:30&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Code Contracts and Pex: Power Charge Your Assertions and Unit Tests&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Mike Barnett, Nikolai Tillmann&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;408A&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Wed 11/18&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;11:30 - 12:30&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Microsoft Perspectives on the Future of Programming&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Panel&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;Petree Hall C&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Wed 11/18&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;12:00 - 13:00&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;F# for Architects – Hitting the Sweet Spot&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Chris Smith&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;VS and .NET Pavillion&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Wed 11/18&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;13:00 - 13:45&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Code Like the Wind with Microsoft Visual Basic 2010&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Lucian Wischik&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;Petree Hall D&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Wed 11/18&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;13:00 - 13:45&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Future of Garbage Collection&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Patrick Dussud&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;Petree Hall C&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Wed 11/18&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;13:00 - 13:45&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Microsoft Project Code Name “M”: The Data and Modeling Language&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Don Box, Jeff Pinkston&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;408A&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Thu&lt;/p&gt;          &lt;p&gt;11/19&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;08:30 - 09:30&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;PLINQ: LINQ, but Faster!&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Ed Essey, Igor Ostrovsky&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;515A&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Thu&lt;/p&gt;          &lt;p&gt;11/19&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;10:00 - 11:00&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;A Lap around Microsoft Visual Studio 2010 for the Visual Basic Developer &lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Lisa Feigenbaum&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;VS and .NET Pavillion&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Thu&lt;/p&gt;          &lt;p&gt;11/19&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;10:00 - 11:00&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Axum: A .NET Language for Safe and Scalable Concurrency&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Niklas Gustafsson&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;515A&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Thu&lt;/p&gt;          &lt;p&gt;11/19&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;11:30 - 12:30&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;F# for Parallel and Asynchronous Programming&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Luke Hoban&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;515A&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Thu&lt;/p&gt;          &lt;p&gt;11/19&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;12:45 - 13:30&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Microsoft Visual C# IDE Tips and Tricks&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;DJ Park&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;Petree Hall D&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="62"&gt;         &lt;p&gt;Thu&lt;/p&gt;          &lt;p&gt;11/19&lt;b&gt;&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="96"&gt;         &lt;p&gt;12:45 - 13:30&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="502"&gt;         &lt;p&gt;&lt;b&gt;Microsoft Visual Basic IDE Tips and Tricks&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="147"&gt;         &lt;p&gt;Dustin Campbell&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="117"&gt;         &lt;p&gt;Petree Hall C&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9922139" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/.NET+Futures/default.aspx">.NET Futures</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/VB/default.aspx">VB</category></item><item><title>Becoming really rich with C#</title><link>http://blogs.msdn.com/lucabol/archive/2009/09/22/becoming-really-rich-with-c.aspx</link><pubDate>Wed, 23 Sep 2009 02:40:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9896982</guid><dc:creator>lucabol</dc:creator><slash:comments>13</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/9896982.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=9896982</wfw:commentRss><description>&lt;P&gt;Or maybe not, please do not hold me responsible if you lose money following this system. Having said that, it is my opinion that there are very few concepts that are important in investing. Three big ones are value, diversification and momentum. This post is about the latter two and how to use C# to create a simple trading system that uses both.&lt;/P&gt;
&lt;P&gt;Diversification is ‘not put all your eggs in one basket’ (contrary to ‘put all of them in one basket and watch that basket’). I don’t believe you can ‘watch’ very much in financial markets, so I tend to prefer diversification.&lt;/P&gt;
&lt;P&gt;Momentum is a mysterious tendency of financial prices that have risen the most in the recent past, to continue outperforming in the close future. In essence, buying the top stocks/sectors/asset classes tends to outperform buying the bottom ones over horizons from three months to one year.&lt;/P&gt;
&lt;P&gt;The idea then is to rank some assets (i.e. ETFs) by how fast they have risen in the past, go long the top ones and short the bottom ones. There are hundreds of variations of this basic strategy, we’ll add the rule that we won’t buy assets that are below their 200 days moving average or sell short assets that are above it.&lt;/P&gt;
&lt;P&gt;I’m writing this code with VS 2010 Beta 2 (which hasn’t shipped yet). It should be trivial to modify it to run on B1 (or maybe it does run on it already). I attach the code and data files to this post.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;struct &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Event &lt;/SPAN&gt;{
    &lt;SPAN style="COLOR: blue"&gt;internal &lt;/SPAN&gt;Event(&lt;SPAN style="COLOR: #2b91af"&gt;DateTime &lt;/SPAN&gt;date, &lt;SPAN style="COLOR: blue"&gt;double &lt;/SPAN&gt;price) { Date = date; Price = price; }
    &lt;SPAN style="COLOR: blue"&gt;internal readonly &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;DateTime &lt;/SPAN&gt;Date;
    &lt;SPAN style="COLOR: blue"&gt;internal readonly double &lt;/SPAN&gt;Price;
}&lt;/PRE&gt;
&lt;P&gt;We’ll use this simple structure to load the closing price for a particular date. My use of internal is kind of bizarre. Actually the whole code might look strange. It is an interesting (maybe un-elegant) mix of object orientation and functional programming.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Summary &lt;/SPAN&gt;{
    &lt;SPAN style="COLOR: blue"&gt;internal &lt;/SPAN&gt;Summary(&lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;ticker, &lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;name, &lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;assetClass,
                    &lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;assetSubClass, &lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt;? weekly, &lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt;? fourWeeks,
                    &lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt;? threeMonths, &lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt;? sixMonths, &lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt;? oneYear,
                    &lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt;? stdDev, &lt;SPAN style="COLOR: blue"&gt;double &lt;/SPAN&gt;price, &lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt;? mav200) {
        Ticker = ticker;
        Name = name;
        AssetClass = assetClass;
        AssetSubClass = assetSubClass;
        &lt;SPAN style="COLOR: green"&gt;// Abracadabra ...
        &lt;/SPAN&gt;LRS = (fourWeeks + threeMonths + sixMonths + oneYear) / &lt;SPAN style="COLOR: brown"&gt;4&lt;/SPAN&gt;;
        Weekly = weekly;
        FourWeeks = fourWeeks;
        ThreeMonths = threeMonths;
        SixMonths = sixMonths;
        OneYear = oneYear;
        StdDev = stdDev;
        Mav200 = mav200;
        Price = price;
    }
    &lt;SPAN style="COLOR: blue"&gt;internal readonly string &lt;/SPAN&gt;Ticker;
    &lt;SPAN style="COLOR: blue"&gt;internal readonly string &lt;/SPAN&gt;Name;
    &lt;SPAN style="COLOR: blue"&gt;internal readonly string &lt;/SPAN&gt;AssetClass;
    &lt;SPAN style="COLOR: blue"&gt;internal readonly string &lt;/SPAN&gt;AssetSubClass;
    &lt;SPAN style="COLOR: blue"&gt;internal readonly double&lt;/SPAN&gt;? LRS;
    &lt;SPAN style="COLOR: blue"&gt;internal readonly double&lt;/SPAN&gt;? Weekly;
    &lt;SPAN style="COLOR: blue"&gt;internal readonly double&lt;/SPAN&gt;? FourWeeks;
    &lt;SPAN style="COLOR: blue"&gt;internal readonly double&lt;/SPAN&gt;? ThreeMonths;
    &lt;SPAN style="COLOR: blue"&gt;internal readonly double&lt;/SPAN&gt;? SixMonths;
    &lt;SPAN style="COLOR: blue"&gt;internal readonly double&lt;/SPAN&gt;? OneYear;
    &lt;SPAN style="COLOR: blue"&gt;internal readonly double&lt;/SPAN&gt;? StdDev;
    &lt;SPAN style="COLOR: blue"&gt;internal readonly double&lt;/SPAN&gt;? Mav200;
    &lt;SPAN style="COLOR: blue"&gt;internal double &lt;/SPAN&gt;Price;

    &lt;SPAN style="COLOR: blue"&gt;internal static void &lt;/SPAN&gt;Banner() {
        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Write(&lt;SPAN style="COLOR: #a31515"&gt;"{0,-6}"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"Ticker"&lt;/SPAN&gt;);
        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Write(&lt;SPAN style="COLOR: #a31515"&gt;"{0,-50}"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"Name"&lt;/SPAN&gt;);
        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Write(&lt;SPAN style="COLOR: #a31515"&gt;"{0,-12}"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"Asset Class"&lt;/SPAN&gt;);
        &lt;SPAN style="COLOR: green"&gt;//Console.Write("{0,-30}\t", "Asset SubClass";
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Write(&lt;SPAN style="COLOR: #a31515"&gt;"{0,4}"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"RS"&lt;/SPAN&gt;);
        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Write(&lt;SPAN style="COLOR: #a31515"&gt;"{0,4}"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"1Wk"&lt;/SPAN&gt;);
        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Write(&lt;SPAN style="COLOR: #a31515"&gt;"{0,4}"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"4Wk"&lt;/SPAN&gt;);
        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Write(&lt;SPAN style="COLOR: #a31515"&gt;"{0,4}"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"3Ms"&lt;/SPAN&gt;);
        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Write(&lt;SPAN style="COLOR: #a31515"&gt;"{0,4}"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"6Ms"&lt;/SPAN&gt;);
        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Write(&lt;SPAN style="COLOR: #a31515"&gt;"{0,4}"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"1Yr"&lt;/SPAN&gt;);
        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Write(&lt;SPAN style="COLOR: #a31515"&gt;"{0,6}"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"Vol"&lt;/SPAN&gt;);
        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.WriteLine(&lt;SPAN style="COLOR: #a31515"&gt;"{0,2}"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"Mv"&lt;/SPAN&gt;);
        &lt;SPAN style="COLOR: green"&gt;//Console.Write("{0,6}", "Pr");
        //Console.WriteLine("{0,6}", "M200");
    &lt;/SPAN&gt;}

    &lt;SPAN style="COLOR: blue"&gt;internal void &lt;/SPAN&gt;Print() {

        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Write(&lt;SPAN style="COLOR: #a31515"&gt;"{0,-6}"&lt;/SPAN&gt;, Ticker);
        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Write(&lt;SPAN style="COLOR: #a31515"&gt;"{0,-50}"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;String&lt;/SPAN&gt;(Name.Take(&lt;SPAN style="COLOR: brown"&gt;48&lt;/SPAN&gt;).ToArray()));
        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Write(&lt;SPAN style="COLOR: #a31515"&gt;"{0,-12}"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;String&lt;/SPAN&gt;(AssetClass.Take(&lt;SPAN style="COLOR: brown"&gt;10&lt;/SPAN&gt;).ToArray()));
        &lt;SPAN style="COLOR: green"&gt;//Console.Write("{0,-30}\t", new String(AssetSubClass.Take(28).ToArray()));
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Write(&lt;SPAN style="COLOR: #a31515"&gt;"{0,4:N0}"&lt;/SPAN&gt;, LRS * &lt;SPAN style="COLOR: brown"&gt;100&lt;/SPAN&gt;);
        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Write(&lt;SPAN style="COLOR: #a31515"&gt;"{0,4:N0}"&lt;/SPAN&gt;, Weekly * &lt;SPAN style="COLOR: brown"&gt;100&lt;/SPAN&gt;);
        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Write(&lt;SPAN style="COLOR: #a31515"&gt;"{0,4:N0}"&lt;/SPAN&gt;, FourWeeks * &lt;SPAN style="COLOR: brown"&gt;100&lt;/SPAN&gt;);
        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Write(&lt;SPAN style="COLOR: #a31515"&gt;"{0,4:N0}"&lt;/SPAN&gt;, ThreeMonths * &lt;SPAN style="COLOR: brown"&gt;100&lt;/SPAN&gt;);
        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Write(&lt;SPAN style="COLOR: #a31515"&gt;"{0,4:N0}"&lt;/SPAN&gt;, SixMonths * &lt;SPAN style="COLOR: brown"&gt;100&lt;/SPAN&gt;);
        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Write(&lt;SPAN style="COLOR: #a31515"&gt;"{0,4:N0}"&lt;/SPAN&gt;, OneYear * &lt;SPAN style="COLOR: brown"&gt;100&lt;/SPAN&gt;);
        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Write(&lt;SPAN style="COLOR: #a31515"&gt;"{0,6:N0}"&lt;/SPAN&gt;, StdDev * &lt;SPAN style="COLOR: brown"&gt;100&lt;/SPAN&gt;);
        &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(Price &amp;lt;= Mav200)
            &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.WriteLine(&lt;SPAN style="COLOR: #a31515"&gt;"{0,2}"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"X"&lt;/SPAN&gt;);
        &lt;SPAN style="COLOR: blue"&gt;else
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.WriteLine();
        &lt;SPAN style="COLOR: green"&gt;//Console.Write("{0,6:N2}", Price);
        //Console.WriteLine("{0,6:N2}", Mav200);
    &lt;/SPAN&gt;}
}&lt;/PRE&gt;
&lt;P&gt;The class Summary above is how I want to present my results. A few comments on the code. I use &lt;EM&gt;Nullable&amp;lt;T&amp;gt;&lt;/EM&gt; because some of this values can be null (i.e. not enough history), but I still don’t want to worry about it. It ends up working rather neatly.&lt;/P&gt;
&lt;P&gt;I also print the results out to &lt;EM&gt;Console, &lt;/EM&gt;which is crazy. I really should be using WPF/Silverlight as the presentation layer. Also the &lt;EM&gt;{0,4:N0}&lt;/EM&gt; notation might be unfamiliar to some of you, but this is how mad &lt;EM&gt;Console&lt;/EM&gt; guys like myself avoid using real UI frameworks. Sometimes we print things in color too.&lt;/P&gt;
&lt;P&gt;The real meat is in the following line:&lt;/P&gt;&lt;PRE class=code&gt;LRS = (fourWeeks + threeMonths + sixMonths + oneYear) / &lt;SPAN style="COLOR: brown"&gt;4&lt;/SPAN&gt;;&lt;/PRE&gt;
&lt;P&gt;That is our highway to richness. It’s a very elaborated quant formula, never before shown, that calculate a magick relative strength (aka momentum) factor as the average of the performance of four weeks, three months, six months and one year.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;TimeSeries &lt;/SPAN&gt;{
    &lt;SPAN style="COLOR: blue"&gt;internal readonly string &lt;/SPAN&gt;Ticker;
    &lt;SPAN style="COLOR: blue"&gt;readonly &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;DateTime &lt;/SPAN&gt;_start;
    &lt;SPAN style="COLOR: blue"&gt;readonly &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Dictionary&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt;&amp;gt; _adjDictionary;
    &lt;SPAN style="COLOR: blue"&gt;readonly string &lt;/SPAN&gt;_name;
    &lt;SPAN style="COLOR: blue"&gt;readonly string &lt;/SPAN&gt;_assetClass;
    &lt;SPAN style="COLOR: blue"&gt;readonly string &lt;/SPAN&gt;_assetSubClass;

    &lt;SPAN style="COLOR: blue"&gt;internal &lt;/SPAN&gt;TimeSeries(&lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;ticker, &lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;name, &lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;assetClass, &lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;assetSubClass, &lt;BR&gt;                                                                &lt;SPAN style="COLOR: #2b91af"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Event&lt;/SPAN&gt;&amp;gt; events) {
        Ticker = ticker;
        _name = name;
        _assetClass = assetClass;
        _assetSubClass = assetSubClass;
        _start = events.Last().Date;
        _adjDictionary = events.ToDictionary(e =&amp;gt; e.Date, e =&amp;gt; e.Price);
    }&lt;/PRE&gt;
&lt;P&gt;I then built myself a little TimeSeries class that represents a series of (date, price). I choose a dictionary to store it because of my assumption that I will be accessing it by date a lot. In retrospect, I was kind of right and kind of wrong. It doesn’t really matter much.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;bool &lt;/SPAN&gt;GetPrice(&lt;SPAN style="COLOR: #2b91af"&gt;DateTime &lt;/SPAN&gt;when, &lt;SPAN style="COLOR: blue"&gt;out double &lt;/SPAN&gt;price, &lt;SPAN style="COLOR: blue"&gt;out double &lt;/SPAN&gt;shift) {
    &lt;SPAN style="COLOR: green"&gt;// To nullify the effect of hours/min/sec/millisec being different from 0
    &lt;/SPAN&gt;when = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt;(when.Year, when.Month, when.Day);
    &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;found = &lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;;
    shift = &lt;SPAN style="COLOR: brown"&gt;1&lt;/SPAN&gt;;
    &lt;SPAN style="COLOR: blue"&gt;double &lt;/SPAN&gt;aPrice = &lt;SPAN style="COLOR: brown"&gt;0&lt;/SPAN&gt;;
    &lt;SPAN style="COLOR: blue"&gt;while &lt;/SPAN&gt;(when &amp;gt;= _start &amp;amp;&amp;amp; !found) {
        &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(_adjDictionary.TryGetValue(when, &lt;SPAN style="COLOR: blue"&gt;out &lt;/SPAN&gt;aPrice)) {
            found = &lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;;
        }
        when = when.AddDays(-&lt;SPAN style="COLOR: brown"&gt;1&lt;/SPAN&gt;);
        shift -= &lt;SPAN style="COLOR: brown"&gt;1&lt;/SPAN&gt;;
    }
    price = aPrice;
    &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;found;
}&lt;/PRE&gt;
&lt;P&gt;A TimeSeries can give you back the price at a particular date. This looks bizarre and complex, but there is a reason for it. I might ask for a date that doesn’t have a price associated with it (i.e. holidays, week-ends). In such cases I want to return the previous price which could be N days in the past.&lt;/P&gt;
&lt;P&gt;I also want to return how many days in the past I had to go, so that other calculations (i.e. &lt;EM&gt;Return&lt;/EM&gt;) can modify their end date by the same amount. Also I might not find such a price at all, in which case I don’t want to throw an exception, but instead notify the caller. In retrospect, I should have used &lt;EM&gt;double?&lt;/EM&gt; to signify ‘price not found’.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt;? GetReturn(&lt;SPAN style="COLOR: #2b91af"&gt;DateTime &lt;/SPAN&gt;start, &lt;SPAN style="COLOR: #2b91af"&gt;DateTime &lt;/SPAN&gt;end) {
    &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;startPrice = &lt;SPAN style="COLOR: brown"&gt;0.0&lt;/SPAN&gt;;
    &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;endPrice = &lt;SPAN style="COLOR: brown"&gt;0.0&lt;/SPAN&gt;;
    &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;shift = &lt;SPAN style="COLOR: brown"&gt;0.0&lt;/SPAN&gt;;
    &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;foundEnd = GetPrice(end, &lt;SPAN style="COLOR: blue"&gt;out &lt;/SPAN&gt;endPrice, &lt;SPAN style="COLOR: blue"&gt;out &lt;/SPAN&gt;shift);
    &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;foundStart = GetPrice(start.AddDays(shift), &lt;SPAN style="COLOR: blue"&gt;out &lt;/SPAN&gt;startPrice, &lt;SPAN style="COLOR: blue"&gt;out &lt;/SPAN&gt;shift);
    &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(!foundStart || !foundEnd)
        &lt;SPAN style="COLOR: blue"&gt;return null&lt;/SPAN&gt;;
    &lt;SPAN style="COLOR: blue"&gt;else
        return &lt;/SPAN&gt;endPrice / startPrice - &lt;SPAN style="COLOR: brown"&gt;1&lt;/SPAN&gt;;
}&lt;/PRE&gt;
&lt;P&gt;We can now go and calculate the return between two dates. Also the &lt;EM&gt;TimeSeries&lt;/EM&gt; object needs to perform a little more calculations.&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN style="COLOR: blue"&gt;internal double&lt;/SPAN&gt;? LastWeekReturn() {
        &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;GetReturn(&lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt;.Now.AddDays(-&lt;SPAN style="COLOR: brown"&gt;7&lt;/SPAN&gt;), &lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt;.Now);
    }
    &lt;SPAN style="COLOR: blue"&gt;internal double&lt;/SPAN&gt;? Last4WeeksReturn() {
        &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;GetReturn(&lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt;.Now.AddDays(-&lt;SPAN style="COLOR: brown"&gt;28&lt;/SPAN&gt;), &lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt;.Now);
    }
    &lt;SPAN style="COLOR: blue"&gt;internal double&lt;/SPAN&gt;? Last3MonthsReturn() {
        &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;GetReturn(&lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt;.Now.AddMonths(-&lt;SPAN style="COLOR: brown"&gt;3&lt;/SPAN&gt;), &lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt;.Now);
    }
    &lt;SPAN style="COLOR: blue"&gt;internal double&lt;/SPAN&gt;? Last6MonthsReturn() {
        &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;GetReturn(&lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt;.Now.AddMonths(-&lt;SPAN style="COLOR: brown"&gt;6&lt;/SPAN&gt;), &lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt;.Now);
    }
    &lt;SPAN style="COLOR: blue"&gt;internal double&lt;/SPAN&gt;? LastYearReturn() {
        &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;GetReturn(&lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt;.Now.AddYears(-&lt;SPAN style="COLOR: brown"&gt;1&lt;/SPAN&gt;), &lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt;.Now);
    }
    &lt;SPAN style="COLOR: blue"&gt;internal double&lt;/SPAN&gt;? StdDev() {
        &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;now = &lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt;.Now;
        now = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt;(now.Year, now.Month, now.Day);
        &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;limit = now.AddYears(-&lt;SPAN style="COLOR: brown"&gt;3&lt;/SPAN&gt;);
        &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;rets = &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;double&lt;/SPAN&gt;&amp;gt;();
        &lt;SPAN style="COLOR: blue"&gt;while &lt;/SPAN&gt;(now &amp;gt;= _start.AddDays(&lt;SPAN style="COLOR: brown"&gt;12&lt;/SPAN&gt;) &amp;amp;&amp;amp; now &amp;gt;= limit) {
            &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;ret = GetReturn(now.AddDays(-&lt;SPAN style="COLOR: brown"&gt;7&lt;/SPAN&gt;), now);
            rets.Add(ret.Value);
            now = now.AddDays(-&lt;SPAN style="COLOR: brown"&gt;7&lt;/SPAN&gt;);
        }
        &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;mean = rets.Average();
        &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;variance = rets.Select(r =&amp;gt; &lt;SPAN style="COLOR: #2b91af"&gt;Math&lt;/SPAN&gt;.Pow(r - mean, &lt;SPAN style="COLOR: brown"&gt;2&lt;/SPAN&gt;)).Sum();
        &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;weeklyStdDev = &lt;SPAN style="COLOR: #2b91af"&gt;Math&lt;/SPAN&gt;.Sqrt(variance / rets.Count);
        &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;weeklyStdDev * &lt;SPAN style="COLOR: #2b91af"&gt;Math&lt;/SPAN&gt;.Sqrt(&lt;SPAN style="COLOR: brown"&gt;40&lt;/SPAN&gt;);
    }
    &lt;SPAN style="COLOR: blue"&gt;internal double&lt;/SPAN&gt;? MAV200() {
        &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;_adjDictionary&lt;BR&gt;               .ToList()&lt;BR&gt;               .OrderByDescending(k =&amp;gt; k.Key)&lt;BR&gt;               .Take(&lt;SPAN style="COLOR: brown"&gt;200)&lt;BR&gt;               &lt;/SPAN&gt;.Average(k =&amp;gt; k.Value);
    }
    &lt;SPAN style="COLOR: blue"&gt;internal double &lt;/SPAN&gt;TodayPrice() {
        &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;price = &lt;SPAN style="COLOR: brown"&gt;0.0&lt;/SPAN&gt;;
        &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;shift = &lt;SPAN style="COLOR: brown"&gt;0.0&lt;/SPAN&gt;;
        GetPrice(&lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt;.Now, &lt;SPAN style="COLOR: blue"&gt;out &lt;/SPAN&gt;price, &lt;SPAN style="COLOR: blue"&gt;out &lt;/SPAN&gt;shift);
        &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;price;
    }
    &lt;SPAN style="COLOR: blue"&gt;internal &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Summary &lt;/SPAN&gt;GetSummary() {
        &lt;SPAN style="COLOR: blue"&gt;return new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Summary&lt;/SPAN&gt;(Ticker, _name, _assetClass, _assetSubClass, &lt;BR&gt;                           LastWeekReturn(), Last4WeeksReturn(), Last3MonthsReturn(),&lt;BR&gt;                           Last6MonthsReturn(), LastYearReturn(), StdDev(), TodayPrice(),&lt;BR&gt;                           MAV200());
    }
}&lt;/PRE&gt;
&lt;P&gt;Nothing particularly interesting in this code. Just a bunch of calculations. The &lt;EM&gt;MAV200&lt;/EM&gt; is the 200 days moving average of closing prices. It shows a more functional way of doing things. The &lt;EM&gt;StdDev&lt;/EM&gt; function is instead very imperative.&lt;/P&gt;
&lt;P&gt;We now can work on downloading the prices. This is how you construct the right URL:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;static string &lt;/SPAN&gt;CreateUrl(&lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;ticker, &lt;SPAN style="COLOR: #2b91af"&gt;DateTime &lt;/SPAN&gt;start, &lt;SPAN style="COLOR: #2b91af"&gt;DateTime &lt;/SPAN&gt;end) {
    &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;@"http://ichart.finance.yahoo.com/table.csv?s=" &lt;/SPAN&gt;+ ticker + &lt;SPAN style="COLOR: #a31515"&gt;"&amp;amp;a="&lt;BR&gt;            &lt;/SPAN&gt;+ (start.Month - &lt;SPAN style="COLOR: brown"&gt;1&lt;/SPAN&gt;).ToString() + &lt;SPAN style="COLOR: #a31515"&gt;"&amp;amp;b=" &lt;/SPAN&gt;+ start.Day.ToString() + &lt;SPAN style="COLOR: #a31515"&gt;"&amp;amp;c="&lt;BR&gt;            &lt;/SPAN&gt;+ start.Year.ToString() + &lt;SPAN style="COLOR: #a31515"&gt;"&amp;amp;d=" &lt;/SPAN&gt;+ (end.Month - &lt;SPAN style="COLOR: brown"&gt;1&lt;/SPAN&gt;).ToString() + &lt;SPAN style="COLOR: #a31515"&gt;"&amp;amp;e="&lt;BR&gt;            &lt;/SPAN&gt;+ end.Day.ToString() + &lt;SPAN style="COLOR: #a31515"&gt;"&amp;amp;f=" &lt;/SPAN&gt;+ end.Year.ToString() + &lt;SPAN style="COLOR: #a31515"&gt;"&amp;amp;g=d&amp;amp;ignore=.csv"&lt;/SPAN&gt;;
}&lt;/PRE&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;And let’s set how many concurrent connections we are going to use …&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ServicePointManager&lt;/SPAN&gt;.DefaultConnectionLimit = &lt;SPAN style="COLOR: brown"&gt;10&lt;/SPAN&gt;;&lt;/PRE&gt;
&lt;P&gt;On my machine, setting this number too high causes errors to be returned. I’m not sure on which side of the connection the problem lies.&lt;/P&gt;
&lt;P&gt;We can then load all the tickers we want to load from a file. One of the files has Leveraged ETFs, which I want to filter out because they tend to pop up always at the top.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;tickers =
    &lt;SPAN style="COLOR: green"&gt;//File.ReadAllLines("ETFs.csv")
    //File.ReadAllLines("ETFTest.csv")
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;File&lt;/SPAN&gt;.ReadAllLines(&lt;SPAN style="COLOR: #a31515"&gt;"AssetClasses.csv"&lt;/SPAN&gt;)
    .Skip(&lt;SPAN style="COLOR: brown"&gt;1&lt;/SPAN&gt;)
    .Select(l =&amp;gt; l.Split(&lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt;[] { &lt;SPAN style="COLOR: #a31515"&gt;',' &lt;/SPAN&gt;}))
    .Where(v =&amp;gt; v[&lt;SPAN style="COLOR: brown"&gt;2&lt;/SPAN&gt;] != &lt;SPAN style="COLOR: #a31515"&gt;"Leveraged"&lt;/SPAN&gt;)
    .Select(values =&amp;gt; &lt;SPAN style="COLOR: #2b91af"&gt;Tuple&lt;/SPAN&gt;.Create(values[&lt;SPAN style="COLOR: brown"&gt;0&lt;/SPAN&gt;], values[&lt;SPAN style="COLOR: brown"&gt;1&lt;/SPAN&gt;], values[&lt;SPAN style="COLOR: brown"&gt;2&lt;/SPAN&gt;], values[&lt;SPAN style="COLOR: brown"&gt;3&lt;/SPAN&gt;]))
    .ToArray();
&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;len = tickers.Length;

&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;start = &lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt;.Now.AddYears(-&lt;SPAN style="COLOR: brown"&gt;2&lt;/SPAN&gt;);
&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;end = &lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt;.Now;
&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;cevent = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;CountdownEvent&lt;/SPAN&gt;(len);
&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;summaries = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Summary&lt;/SPAN&gt;[len];&lt;/PRE&gt;
&lt;P&gt;And then load all of them, making sure to make an asynchronous call so not to keep the thread busy.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: #2b91af"&gt;for(var i = &lt;/SPAN&gt;&lt;SPAN style="COLOR: brown"&gt;0;&lt;/SPAN&gt; i &amp;lt; len; i++)  {
    &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;t = tickers[i];
    &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;url = CreateUrl(t.Item1, start, end);
    &lt;SPAN style="COLOR: blue"&gt;using &lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;webClient = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;WebClient&lt;/SPAN&gt;()) {
        webClient.DownloadStringCompleted +=&lt;BR&gt;                          &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;DownloadStringCompletedEventHandler&lt;/SPAN&gt;(downloadStringCompleted);
        webClient.DownloadStringAsync(&lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Uri&lt;/SPAN&gt;(url), &lt;SPAN style="COLOR: #2b91af"&gt;Tuple&lt;/SPAN&gt;.Create(t, cevent, summaries, i));
    }
}

cevent.Wait();&lt;/PRE&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Notice the use of a Countdown event to wait for all the thread to complete before printing out the results. Also notice the new &lt;EM&gt;Tuple&amp;lt;T&amp;gt;&lt;/EM&gt; class used to package things to send around.&lt;/P&gt;
&lt;P&gt;We can then print out the top and bottom 15%:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;top15perc =
        summaries
        .Where(s =&amp;gt; s.LRS.HasValue)
        .OrderByDescending(s =&amp;gt; s.LRS)
        .Take((&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;)(len * &lt;SPAN style="COLOR: brown"&gt;0.15&lt;/SPAN&gt;));
&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;bottom15perc =
        summaries
        .Where(s =&amp;gt; s.LRS.HasValue)
        .OrderBy(s =&amp;gt; s.LRS)
        .Take((&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;)(len * &lt;SPAN style="COLOR: brown"&gt;0.15&lt;/SPAN&gt;));

&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.WriteLine();
&lt;SPAN style="COLOR: #2b91af"&gt;Summary&lt;/SPAN&gt;.Banner();
&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.WriteLine(&lt;SPAN style="COLOR: #a31515"&gt;"TOP 15%"&lt;/SPAN&gt;);
&lt;SPAN style="COLOR: blue"&gt;foreach&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;s &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;top15perc)
    s.Print();

&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.WriteLine();
&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.WriteLine(&lt;SPAN style="COLOR: #a31515"&gt;"Bottom 15%"&lt;/SPAN&gt;);
&lt;SPAN style="COLOR: blue"&gt;foreach &lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;s &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;bottom15perc)
    s.Print();&lt;/PRE&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Here is what we do when a request comes back with data:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;static void &lt;/SPAN&gt;downloadStringCompleted(&lt;SPAN style="COLOR: blue"&gt;object &lt;/SPAN&gt;sender, &lt;SPAN style="COLOR: #2b91af"&gt;DownloadStringCompletedEventArgs &lt;/SPAN&gt;e) {
    &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;bigTuple =&lt;BR&gt;             (&lt;SPAN style="COLOR: #2b91af"&gt;Tuple&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Tuple&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;&amp;gt;, &lt;SPAN style="COLOR: #2b91af"&gt;CountdownEvent&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #2b91af"&gt;Summary&lt;/SPAN&gt;[], &lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;&amp;gt;)&lt;BR&gt;              e.UserState;
    &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;tuple = bigTuple.Item1;
    &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;cevent = bigTuple.Item2;
    &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;summaries = bigTuple.Item3;
    &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;i = bigTuple.Item4;
    &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;ticker = tuple.Item1;
    &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;name = tuple.Item2;
    &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;asset = tuple.Item3;
    &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;subAsset = tuple.Item4;

    &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(e.Error == &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;) {
        &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;adjustedPrices =
                e.Result
                .Split(&lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt;[] { &lt;SPAN style="COLOR: #a31515"&gt;'\n' &lt;/SPAN&gt;})
                .Skip(&lt;SPAN style="COLOR: brown"&gt;1&lt;/SPAN&gt;)
                .Select(l =&amp;gt; l.Split(&lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt;[] { &lt;SPAN style="COLOR: #a31515"&gt;',' &lt;/SPAN&gt;}))
                .Where(l =&amp;gt; l.Length == &lt;SPAN style="COLOR: brown"&gt;7&lt;/SPAN&gt;)
                .Select(v =&amp;gt; &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Event&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;DateTime&lt;/SPAN&gt;.Parse(v[&lt;SPAN style="COLOR: brown"&gt;0&lt;/SPAN&gt;]), &lt;SPAN style="COLOR: #2b91af"&gt;Double&lt;/SPAN&gt;.Parse(v[&lt;SPAN style="COLOR: brown"&gt;6&lt;/SPAN&gt;])));

        &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;timeSeries = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;TimeSeries&lt;/SPAN&gt;(ticker, name, asset, subAsset, adjustedPrices);
        summaries[i] = timeSeries.GetSummary();
        cevent.Signal();
        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.Write(&lt;SPAN style="COLOR: #a31515"&gt;"{0} "&lt;/SPAN&gt;, ticker);
    }
    &lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;{
        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.WriteLine(&lt;SPAN style="COLOR: #a31515"&gt;"[{0} ERROR] "&lt;/SPAN&gt;, ticker);
        &lt;SPAN style="COLOR: green"&gt;//Console.WriteLine(e.Error);
        &lt;/SPAN&gt;summaries[i] = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Summary&lt;/SPAN&gt;(ticker, name, &lt;SPAN style="COLOR: #a31515"&gt;"ERROR"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"ERROR"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: brown"&gt;0&lt;/SPAN&gt;, &lt;SPAN style="COLOR: brown"&gt;0&lt;/SPAN&gt;, &lt;SPAN style="COLOR: brown"&gt;0&lt;/SPAN&gt;, &lt;SPAN style="COLOR: brown"&gt;0&lt;/SPAN&gt;, &lt;SPAN style="COLOR: brown"&gt;0&lt;/SPAN&gt;, &lt;SPAN style="COLOR: brown"&gt;0&lt;/SPAN&gt;,&lt;SPAN style="COLOR: brown"&gt;0&lt;/SPAN&gt;,&lt;SPAN style="COLOR: brown"&gt;0&lt;/SPAN&gt;); 
        cevent.Signal();
    }
}&lt;/PRE&gt;
&lt;P&gt;We first unpack the &lt;EM&gt;Tuple&lt;/EM&gt; we sent out originally, we then extract the Date and Price, create a &lt;EM&gt;Summary &lt;/EM&gt;object and store it in the &lt;EM&gt;summaries&lt;/EM&gt; array. It’s important to remember to &lt;EM&gt;Signal&lt;/EM&gt; to the &lt;EM&gt;cevent&lt;/EM&gt; in the error case as well because we want to print out the results even if some downloading failed.&lt;/P&gt;
&lt;P&gt;And here is what you get for your effort:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/lucabol/WindowsLiveWriter/BecomingreallyrichwithC_C128/image_2.png" mce_href="http://blogs.msdn.com/blogfiles/lucabol/WindowsLiveWriter/BecomingreallyrichwithC_C128/image_2.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/lucabol/WindowsLiveWriter/BecomingreallyrichwithC_C128/image_thumb.png" width=743 height=506 mce_src="http://blogs.msdn.com/blogfiles/lucabol/WindowsLiveWriter/BecomingreallyrichwithC_C128/image_thumb.png"&gt;&lt;/A&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9896982" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/lucabol/attachment/9896982.ashx" length="15441" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category></item><item><title>A version of the AsyncCache found its way into the Parallel Programming samples …</title><link>http://blogs.msdn.com/lucabol/archive/2009/05/21/a-version-of-the-asynccache-found-its-way-into-the-parallel-programming-samples.aspx</link><pubDate>Thu, 21 May 2009 20:28:13 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9634050</guid><dc:creator>lucabol</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/9634050.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=9634050</wfw:commentRss><description>&lt;p&gt;Go &lt;a href="http://code.msdn.microsoft.com/ParExtSamples"&gt;here&lt;/a&gt; to download them. It is in \ParallelExtensionsExtras\CoordinationDataStructures. It has a slightly different design in that it returns Tasks. I’m trying to get &lt;a href="http://blogs.msdn.com/pfxteam"&gt;Stephen&lt;/a&gt; to blog about it so that you can compare them.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9634050" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/VB/default.aspx">VB</category></item><item><title>I talk about C# and VB Co-Evolution on Channel9 (and some F# …)</title><link>http://blogs.msdn.com/lucabol/archive/2009/05/14/i-talk-about-c-and-vb-co-evolution-on-channel9-and-some-f.aspx</link><pubDate>Thu, 14 May 2009 20:26:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9616619</guid><dc:creator>lucabol</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/9616619.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=9616619</wfw:commentRss><description>&lt;p&gt;The title says it all. If you are interested, go &lt;a href="http://channel9.msdn.com/posts/Charles/Luca-Bolognese-C-and-VBNET-Co-Evolution-The-Twain-Shall-Meet/#Page=2"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9616619" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/VB/default.aspx">VB</category></item><item><title>Luca at NDC in Oslo 17 – 19 June 2009</title><link>http://blogs.msdn.com/lucabol/archive/2009/03/24/luca-at-ndc-in-oslo-17-19-june-2009.aspx</link><pubDate>Tue, 24 Mar 2009 19:46:27 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9504664</guid><dc:creator>lucabol</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/9504664.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=9504664</wfw:commentRss><description>&lt;p&gt;I’ll be speaking about the future of C# and F#. Oslo brings back so many memories …&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/lucabol/WindowsLiveWriter/LucaatNDCinOslo1719June2009_8952/Logo%20NDC%202009_2.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Logo NDC 2009" border="0" alt="Logo NDC 2009" src="http://blogs.msdn.com/blogfiles/lucabol/WindowsLiveWriter/LucaatNDCinOslo1719June2009_8952/Logo%20NDC%202009_thumb.jpg" width="244" height="72" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;“one of the world’s most important conferences for IT developers and leaders”&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9504664" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/F_2300_/default.aspx">F#</category></item><item><title>Simulating INumeric with dynamic in C# 4.0</title><link>http://blogs.msdn.com/lucabol/archive/2009/02/05/simulating-inumeric-with-dynamic-in-c-4-0.aspx</link><pubDate>Thu, 05 Feb 2009 19:47:26 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9399063</guid><dc:creator>lucabol</dc:creator><slash:comments>30</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/9399063.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=9399063</wfw:commentRss><description>&lt;p&gt;When I wrote my &lt;a href="http://blogs.msdn.com/lucabol/archive/2008/12/04/financial-functions-for-net-released.aspx"&gt;Excel financial library&lt;/a&gt; I agonized over the decision of which numeric type to use to represent money. Logic would push me toward &lt;em&gt;decimal&lt;/em&gt;, but common usage among financial library writers would push me toward &lt;em&gt;double&lt;/em&gt;. I ended up picking double, but I regret having to make that choice in the first place.&lt;/p&gt;  &lt;p&gt;Conceptually, I'd like my numeric functions to work for anything that supports the basic arithmetic operators (i.e. +, -, * ...). Unfortunately that is not possible in .NET at this point in time. In essence you have to write your code twice as below.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="background: white"&gt;   &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;static double &lt;/span&gt;&lt;span style="background: white"&gt;SumDouble(&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;double &lt;/span&gt;&lt;span style="background: white"&gt;a, &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;double &lt;/span&gt;&lt;span style="background: white"&gt;b) { &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;return &lt;/span&gt;&lt;span style="background: white"&gt;a + b; }
   &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;static decimal &lt;/span&gt;&lt;span style="background: white"&gt;SumDecimal(&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;decimal &lt;/span&gt;&lt;span style="background: white"&gt;a, &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;decimal &lt;/span&gt;&lt;span style="background: white"&gt;b) {&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;return &lt;/span&gt;&lt;span style="background: white"&gt;a + b;}&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Granted, this is not a good state of affairs. We often discussed how to make it work, but we couldn't find a solution that was both fast to run and cheap for us to implement. More often than not we speculated about having the numeric types implement a specific &lt;em&gt;INumeric&lt;/em&gt; interface and add a generic constraint to the C#/VB languages to make it work. Hence the title of this post.&lt;/p&gt;

&lt;p&gt;With we implemented &lt;em&gt;dynamic&lt;/em&gt; in C# 4.0 it occurred to me that you can fake your way into writing your code just once. For sure, this solution doesn't have the same performance characteristics of 'writing your code twice', but at least it doesn't duplicate your code.&lt;/p&gt;

&lt;p&gt;This is how it looks like:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background: white"&gt;    &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;static dynamic &lt;/span&gt;&lt;span style="background: white"&gt;Sum1(&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;dynamic &lt;/span&gt;&lt;span style="background: white"&gt;a, &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;dynamic &lt;/span&gt;&lt;span style="background: white"&gt;b) { &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;return &lt;/span&gt;&lt;span style="background: white"&gt;a + b; }&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;The call to the '+' operator is resolved at runtime, by the C# binder, hence a performance penalty is incurred. The penalty is less than you might think, given that the &lt;a href="http://www.codeplex.com/dlr"&gt;DLR&lt;/a&gt; caches things under the cover so that no v-table lookup is performed the second time around. The whole thing is explained in more detail &lt;a href="http://blogs.msdn.com/cburrows/archive/2008/10/27/c-dynamic.aspx"&gt;here&lt;/a&gt;. But still, it is not as fast as a normal '+' operator over a primitive type. I'll let you enjoy micro performance testing this one :-)&lt;/p&gt;

&lt;p&gt;A slight refinement is to make the code generic so that a caller doesn't see a signature with dynamic types as arguments.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background: white"&gt;   &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;static dynamic &lt;/span&gt;&lt;span style="background: white"&gt;Sum2&amp;lt;T1, T2&amp;gt;(T1 a, T2 b)
   {
       &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;dynamic &lt;/span&gt;&lt;span style="background: white"&gt;ad = a;
       &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;dynamic &lt;/span&gt;&lt;span style="background: white"&gt;bd = b;
       &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;return &lt;/span&gt;&lt;span style="background: white"&gt;ad + bd;
   }&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;I could make the return type generic as well, but that would force the caller to be explicit about the types, making the calling code much less readable. The other good thing about this signature is that you get a different call site with each combination of type arguments and, since they are separate, the binding caches should stay small. With the former signature there is only one call site and the cache could pile up to the point where the DLR decides to discard it.&lt;/p&gt;

&lt;p&gt;Here is how the calling code looks like right now:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background: white"&gt;       &lt;/span&gt;&lt;span style="background: white; color: #2b91af"&gt;Console&lt;/span&gt;&lt;span style="background: white"&gt;.WriteLine(Sum2(2m, 4m));
       &lt;/span&gt;&lt;span style="background: white; color: #2b91af"&gt;Console&lt;/span&gt;&lt;span style="background: white"&gt;.WriteLine(Sum2(2.0, 4.0));
       &lt;/span&gt;&lt;span style="background: white; color: #2b91af"&gt;Console&lt;/span&gt;&lt;span style="background: white"&gt;.WriteLine(Sum2(&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;new &lt;/span&gt;&lt;span style="background: white; color: #2b91af"&gt;DateTime&lt;/span&gt;&lt;span style="background: white"&gt;(2000,12,1), &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;new &lt;/span&gt;&lt;span style="background: white; color: #2b91af"&gt;TimeSpan&lt;/span&gt;&lt;span style="background: white"&gt;(24,0,0)));&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Yet another way to write this code is as follows:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background: white"&gt;   &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;public static &lt;/span&gt;&lt;span style="background: white"&gt;T Sum3&amp;lt;T&amp;gt;(T a, T b)
   {

       &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;dynamic &lt;/span&gt;&lt;span style="background: white"&gt;ad = a;
       &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;dynamic &lt;/span&gt;&lt;span style="background: white"&gt;bd = b;
       &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;return &lt;/span&gt;&lt;span style="background: white"&gt;ad + bd;
   }&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;This gets around the problem of showing a dynamic return value and give you some more compile time type checking. But it prevents summing not coercible types. The compiler doesn't let you get there. The last line below wont' compile:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background: white"&gt;       &lt;/span&gt;&lt;span style="background: white; color: #2b91af"&gt;Console&lt;/span&gt;&lt;span style="background: white"&gt;.WriteLine(Sum3(2m, 4m));
       &lt;/span&gt;&lt;span style="background: white; color: #2b91af"&gt;Console&lt;/span&gt;&lt;span style="background: white"&gt;.WriteLine(Sum3(2.0, 4.0));
       &lt;/span&gt;&lt;span style="background: white; color: green"&gt;//Console.WriteLine(Sum3(new DateTime(2000,12,1), new TimeSpan(24,0,0)));&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Also notice that in VB you could have done this a long time ago :-)&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="background: white"&gt;   &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;Function &lt;/span&gt;&lt;span style="background: white"&gt;Sum(Of T1, T2)(&lt;/span&gt;&lt;span style="background: white; color: blue"&gt;ByVal &lt;/span&gt;&lt;span style="background: white"&gt;a &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;As &lt;/span&gt;&lt;span style="background: white; color: #2b91af"&gt;T1&lt;/span&gt;&lt;span style="background: white"&gt;, &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;ByVal &lt;/span&gt;&lt;span style="background: white"&gt;b &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;As &lt;/span&gt;&lt;span style="background: white; color: #2b91af"&gt;T2&lt;/span&gt;&lt;span style="background: white"&gt;)
       &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;Dim &lt;/span&gt;&lt;span style="background: white"&gt;aa &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;As Object &lt;/span&gt;&lt;span style="background: white"&gt;= a
       &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;Dim &lt;/span&gt;&lt;span style="background: white"&gt;bb &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;As Object &lt;/span&gt;&lt;span style="background: white"&gt;= b
       &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;Return &lt;/span&gt;&lt;span style="background: white"&gt;aa + bb
   &lt;/span&gt;&lt;span style="background: white; color: blue"&gt;End Function&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;In summary, by using dynamic you can write your numeric code just once, but you pay a performance price. You are the only one who can decide if the price is worth paying in your particular application. As often, the profiler is your friend.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9399063" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category></item><item><title>Financial Functions for .NET released !</title><link>http://blogs.msdn.com/lucabol/archive/2008/12/04/financial-functions-for-net-released.aspx</link><pubDate>Fri, 05 Dec 2008 00:40:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9177026</guid><dc:creator>lucabol</dc:creator><slash:comments>12</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/9177026.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=9177026</wfw:commentRss><description>&lt;P&gt;Today I released the following library on CodeGallery. It is the result of three months of coding during my paternity leave in Italy. You can get it from &lt;A href="http://code.msdn.microsoft.com/FinancialFunctions" mce_href="http://code.msdn.microsoft.com/FinancialFunctions"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;What is it?&lt;/B&gt; &lt;BR&gt;This is a .NET library that provides the full set of financial functions from Excel. The main goal for the library is compatibility with Excel, by providing the same functions, with the same behaviour. Note though that this is not a wrapper over the Excel library; the functions have been re-implemented in managed code so that you do not need to have Excel installed to use this library.&amp;nbsp;&lt;BR&gt;&lt;B&gt;&amp;nbsp;&lt;BR&gt;&lt;/B&gt;&lt;B&gt;Where I can find documentation on these functions?&lt;/B&gt; &lt;BR&gt;Just open Excel and click on Formulas/Financial or go to &lt;A href="http://office.microsoft.com/client/helppreview.aspx?AssetID=HP100791841033&amp;amp;ns=EXCEL&amp;amp;lcid=1033&amp;amp;CTT=3&amp;amp;Origin=HP100623561033" mce_href="http://office.microsoft.com/client/helppreview.aspx?AssetID=HP100791841033&amp;amp;ns=EXCEL&amp;amp;lcid=1033&amp;amp;CTT=3&amp;amp;Origin=HP100623561033"&gt;this&lt;/A&gt; &lt;BR&gt;&lt;B&gt;&lt;BR&gt;I don't think one of the function is right. Excel produces the wrong results! Why don't you do it right?&lt;/B&gt; &lt;BR&gt;My goal is to replicate Excel results (right and wrong). Feel free to contribute to the effort by coding what you think is the right solution and I'll add an ExcelCompliant flag to the function to conditionally invoke your code. &lt;BR&gt;&lt;B&gt;&lt;BR&gt;How do I use the library?&lt;/B&gt; &lt;BR&gt;Just add Financial.dll to the references in your project. The functions are provided as static methods on a Financial class in the System.Numeric namespace &lt;BR&gt;&lt;B&gt;I see the library was implemented with F#. But I don’t want to redistribute F# along with my application. What should I do?&lt;/B&gt; &lt;BR&gt;There are two versions of the library. One of them statically links the F# libraries so that there is no dependency on F#. However, this assembly larger, so if you have F# installed, you can use the FinancialNotStandalone.dll instead. &lt;BR&gt;&lt;B&gt;&lt;BR&gt;How do I run the tests?&lt;/B&gt; &lt;BR&gt;Run FinancialTests.exe. You need Excel 12 for the tests to work because they use Excel to test that the results are correct. You don't need Excel 12 to use the library in your own application. &lt;BR&gt;&lt;B&gt;&lt;BR&gt;How do I compile the library?&lt;/B&gt; &lt;BR&gt;You need to have F# September CTP installed (you can get it from &lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=61ad6924-93ad-48dc-8c67-60f7e7803d3c" mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyID=61ad6924-93ad-48dc-8c67-60f7e7803d3c"&gt;here&lt;/A&gt;). There are two batch files (CreateLibraryStandalone.bat and CreateLibraryNotStandalon.bat). Run them to compile the dll. You might have to change the path to the F# compiler inside these files &lt;BR&gt;&lt;B&gt;&lt;BR&gt;How do I compile the tests?&lt;/B&gt; &lt;BR&gt;Run CreateTests.bat &lt;BR&gt;&lt;B&gt;&lt;BR&gt;Have you tested this thing?&lt;/B&gt; &lt;BR&gt;Yes, I do have 201,349 testcases running against it. You can easily raise that number significantly by adding new values to test in testdef.fs. If you have a multiproc machine the testcases will run faster as I parallelize their execution. &lt;BR&gt;&lt;B&gt;&lt;BR&gt;Have you run performance tests on it?&lt;/B&gt; &lt;BR&gt;Not at all. The only thing I checked is that all the recursive functions are tail recursive. Feel free to let me know if they are slow. &lt;BR&gt;&lt;B&gt;&lt;BR&gt;Are there any functions that behave different from Excel?&lt;/B&gt; &lt;BR&gt;Yes, there are two of them. &lt;BR&gt;&lt;I&gt;CoupDays&lt;/I&gt; &lt;BR&gt;The Excel algorithm seems wrong in that it doesn't respect the following: &lt;BR&gt;coupDays = coupDaysBS + coupDaysNC. &lt;BR&gt;This equality should stand. By manually counting the days, I'm pretty confident that my algorithm is correct.My result differs from Excel by +/- one or two days when the date spans a leap year. &lt;BR&gt;&lt;I&gt;VDB&lt;/I&gt; &lt;BR&gt;In the excel version of this algorithm the depreciation in the period (0,1) is not the same as the sum of the depreciations in periods (0,0.5) (0.5,1). &lt;BR&gt;VDB(100,10,13,0,0.5,1,0) + VDB(100,10,13,0.5,1,1,0) &amp;lt;&amp;gt; VDB(100,10,13,0,1,1,0) &lt;BR&gt;Notice that in Excel by using '1' (no_switch) instead of '0' as the last parameter everything works as expected. The last parameter should have no influence in the calculation given that in the first period there is no switch to sln depreciation. &lt;BR&gt;Overall, I think my algorithm is correct, even if it disagrees with Excel when startperiod is fractional. &lt;BR&gt;&lt;B&gt;&lt;BR&gt;Can you list the functions with their testcases results?&lt;/B&gt; &lt;BR&gt;Succeeded 1840/1840 for PV &lt;BR&gt;Succeeded 2024/2024 for FV &lt;BR&gt;Succeeded 2240/2240 for PMT &lt;BR&gt;Succeeded 853/853 for NPER &lt;BR&gt;Succeeded 5355/5355 for IPMT &lt;BR&gt;Succeeded 5355/5355 for PPMT &lt;BR&gt;Succeeded 208/208 for CUMIPMT &lt;BR&gt;Succeeded 208/208 for CUMPRINC &lt;BR&gt;Succeeded 624/624 for ISPMT &lt;BR&gt;Succeeded 12/12 for FVSCHEDULE &lt;BR&gt;Succeeded 9/9 for IRR &lt;BR&gt;Succeeded 21/21 for NPV &lt;BR&gt;Succeeded 147/147 for MIRR &lt;BR&gt;Succeeded 18/18 for XIRR &lt;BR&gt;Succeeded 396/396 for DB &lt;BR&gt;Succeeded 24/24 for SLN &lt;BR&gt;Succeeded 132/132 for SYD &lt;BR&gt;Succeeded 456/456 for DDB &lt;BR&gt;Succeeded 2544/2544 for VDB excluding fractional startdates &lt;BR&gt;Succeeded 11520/11520 for AMORLINC &lt;BR&gt;Succeeded 23040/23040 for AMORDEGRC &lt;BR&gt;Succeeded 15/15 for COUPDAYS excluding leap years &lt;BR&gt;Succeeded 915/915 for COUPDAYSBS &lt;BR&gt;Succeeded 915/915 for COUPDAYSNC &lt;BR&gt;Succeeded 915/915 for COUPNUM &lt;BR&gt;Succeeded 915/915 for COUPPCD &lt;BR&gt;Succeeded 915/915 for COUPNCD &lt;BR&gt;Succeeded 360/360 for ACCRINTM &lt;BR&gt;Succeeded 1920/1920 for ACCRINT &lt;BR&gt;Succeeded 10980/10980 for PRICE &lt;BR&gt;Succeeded 1940/1940 for PRICEMAT &lt;BR&gt;Succeeded 2910/2910 for YIELDMAT &lt;BR&gt;Succeeded 1395/1395 for YEARFRAC &lt;BR&gt;Succeeded 2745/2745 for INTRATE &lt;BR&gt;Succeeded 1290/1290 for RECEIVED &lt;BR&gt;Succeeded 2745/2745 for DISC &lt;BR&gt;Succeeded 3660/3660 for PRICEDISC &lt;BR&gt;Succeeded 2745/2745 for YIELDDISC &lt;BR&gt;Succeeded 48/48 for TBILLEQ &lt;BR&gt;Succeeded 69/69 for TBILLYIELD &lt;BR&gt;Succeeded 81/81 for TBILLPrice &lt;BR&gt;Succeeded 12/12 for DOLLARDE &lt;BR&gt;Succeeded 12/12 for DOLLARFR &lt;BR&gt;Succeeded 12/12 for EFFECT &lt;BR&gt;Succeeded 12/12 for NOMINAL &lt;BR&gt;Succeeded 5490/5490 for DURATION &lt;BR&gt;Succeeded 5490/5490 for MDURATION &lt;BR&gt;Succeeded 19320/19320 for ODDFPRICE &lt;BR&gt;Succeeded 30600/30600 for ODDLPRICE &lt;BR&gt;Succeeded 45900/45900 for ODDLYIELD &lt;BR&gt;Test Cases Succeeded 201349/201349&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9177026" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/Financial/default.aspx">Financial</category><category domain="http://blogs.msdn.com/lucabol/archive/tags/F_2300_/default.aspx">F#</category></item><item><title>A C# library to write functional code - Part V - The Match operator</title><link>http://blogs.msdn.com/lucabol/archive/2008/07/15/a-c-library-to-write-functional-code-part-v-the-match-operator.aspx</link><pubDate>Tue, 15 Jul 2008 12:46:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8732828</guid><dc:creator>lucabol</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/8732828.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=8732828</wfw:commentRss><description>&lt;P&gt;Other posts in the series:&lt;/P&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/04/01/a-c-library-to-write-functional-code-part-i-background.aspx"&gt;&lt;STRONG&gt;&lt;FONT color=#006bad&gt;Part I - Background&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx"&gt;&lt;STRONG&gt;&lt;FONT color=#006bad&gt;Part II - Tuples&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt; 
&lt;LI&gt;&lt;STRONG&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/04/21/a-c-library-to-write-functional-code-part-iii-records.aspx"&gt;&lt;FONT color=#006bad&gt;Part III - Records&lt;/FONT&gt;&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A class="" href="http://blogs.msdn.com/lucabol/archive/2008/06/06/a-c-library-to-write-functional-code-part-iv-type-unions.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2008/06/06/a-c-library-to-write-functional-code-part-iv-type-unions.aspx"&gt;Part IV - Type Unions&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A class="" href="http://blogs.msdn.com/lucabol/archive/2008/07/15/a-c-library-to-write-functional-code-part-v-the-match-operator.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2008/07/15/a-c-library-to-write-functional-code-part-v-the-match-operator.aspx"&gt;Part V - The Match operator&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;P&gt;This is my last post of this series. It is about the &lt;EM&gt;match&lt;/EM&gt; operator. To the untrained eyes this operator might look like a case statement. But they are different.&lt;/P&gt;
&lt;P&gt;The &lt;EM&gt;match&lt;/EM&gt; operator combines control flow and decomposition in a single construct. As it often happens, even if these two things are well known concepts, putting them together gives you a different perspective on your code.&lt;/P&gt;
&lt;P&gt;I have to admit that the similarity with a case statement triggered all sorts of bad reactions in my OO trained mind. Phrases from wise gurus on the tone of "never use an 'if' statement" was echoing in my mind. After a while I got over it and enjoyed the power that this operator gives.&lt;/P&gt;
&lt;P&gt;In this library we won't get close to the beauty of the &lt;EM&gt;match&lt;/EM&gt; operator in functional languages (i.e. F#), especially the decomposition piece. There might be a way to do better than this in C#, but this was enough for my purpose of learning about functional programming, so I didn't investigate further. Learning was my real goal.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;How to use it&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;There are two versions of this operator. Let's start from the more eye pleasing one.&lt;/P&gt;
&lt;P&gt;Let's assume a discriminated union like the following:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Node &lt;/SPAN&gt;: &lt;SPAN style="COLOR: #2b91af"&gt;TypeUnion&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;&amp;gt; {

    &lt;SPAN style="COLOR: blue"&gt;public &lt;/SPAN&gt;Node(&lt;SPAN style="COLOR: blue"&gt;int &lt;/SPAN&gt;i) : &lt;SPAN style="COLOR: blue"&gt;base&lt;/SPAN&gt;(i) { }
    &lt;SPAN style="COLOR: blue"&gt;public &lt;/SPAN&gt;Node(&lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;s) : &lt;SPAN style="COLOR: blue"&gt;base&lt;/SPAN&gt;(s) { }

    &lt;SPAN style="COLOR: blue"&gt;public int &lt;/SPAN&gt;IntNode { &lt;SPAN style="COLOR: blue"&gt;get &lt;/SPAN&gt;{ &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;Type1; } }
    &lt;SPAN style="COLOR: blue"&gt;public string &lt;/SPAN&gt;StringNode { &lt;SPAN style="COLOR: blue"&gt;get &lt;/SPAN&gt;{ &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;Type2; } }
}&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;I can then match against this union with the following code:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;no = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Node&lt;/SPAN&gt;(35);

r = &lt;SPAN style="COLOR: #2b91af"&gt;F&lt;/SPAN&gt;.Match(no, 
                (&lt;SPAN style="COLOR: blue"&gt;int &lt;/SPAN&gt;i)    =&amp;gt; (i + 3).ToString(),
                (&lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;s) =&amp;gt; s&lt;BR&gt;            );

&lt;SPAN style="COLOR: #2b91af"&gt;Assert&lt;/SPAN&gt;.AreEqual(&lt;SPAN style="COLOR: #a31515"&gt;"38"&lt;/SPAN&gt;, r);&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Note that the &lt;EM&gt;match&lt;/EM&gt; operator behaves a bit like a case statement, but it also gives you the 'right' type on the right of the '=&amp;gt;' for you to write code against.&lt;/P&gt;
&lt;P&gt;I have to admit I'm rather happy of this syntax, but it has one severe limitation. You need to specify all the types of the type union and they have to be in the same order. For example, in the previous code I cannot match against &lt;EM&gt;string&lt;/EM&gt; first and &lt;EM&gt;int&lt;/EM&gt; second. I consider this to be a big deal.&lt;/P&gt;
&lt;P&gt;A different implementation of match that doesn't have that limitation is as follows:&lt;/P&gt;&lt;PRE class=code&gt;no = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Node&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"35"&lt;/SPAN&gt;);
r = &lt;SPAN style="COLOR: #2b91af"&gt;F&lt;/SPAN&gt;.Match(no,
    n =&amp;gt; n.Is&amp;lt;&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;&amp;gt;(),   n =&amp;gt; (n.As&amp;lt;&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;&amp;gt;() + 3).ToString(),
    n =&amp;gt; n.Is&amp;lt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;&amp;gt;(),n =&amp;gt; n.As&amp;lt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;&amp;gt;());

&lt;SPAN style="COLOR: #2b91af"&gt;Assert&lt;/SPAN&gt;.AreEqual(&lt;SPAN style="COLOR: #a31515"&gt;"35"&lt;/SPAN&gt;, r);&lt;/PRE&gt;
&lt;P&gt;Rather less pleasing to the eyes, but more robust to use.&lt;/P&gt;
&lt;P&gt;By using this more generic version, you can obviously match against all the constructs we described in this series. I.E. against &lt;EM&gt;Tuples&lt;/EM&gt;:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;t = &lt;SPAN style="COLOR: #2b91af"&gt;F&lt;/SPAN&gt;.Tuple(&lt;SPAN style="COLOR: #a31515"&gt;"msft"&lt;/SPAN&gt;, 10, &lt;SPAN style="COLOR: #a31515"&gt;"Nasdaq"&lt;/SPAN&gt;);

&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;r = &lt;SPAN style="COLOR: #2b91af"&gt;F&lt;/SPAN&gt;.Match(t,
    i =&amp;gt; i.Item2 &amp;lt; 5 &amp;amp;&amp;amp; i.Item3 == &lt;SPAN style="COLOR: #a31515"&gt;"OTC"&lt;/SPAN&gt;, &lt;BR&gt;         i =&amp;gt; i.Item1 + &lt;SPAN style="COLOR: #a31515"&gt;" is low price OTC stock"&lt;/SPAN&gt;,
    i =&amp;gt; i.Item3 == &lt;SPAN style="COLOR: #a31515"&gt;"OTC"&lt;/SPAN&gt;,&lt;BR&gt;         i =&amp;gt; i.Item1 + &lt;SPAN style="COLOR: #a31515"&gt;"is a normal OTC stock"&lt;/SPAN&gt;,
    i =&amp;gt; i.Item3 == &lt;SPAN style="COLOR: #a31515"&gt;"Nasdaq"&lt;/SPAN&gt;, &lt;BR&gt;         i =&amp;gt; i.Item1 + &lt;SPAN style="COLOR: #a31515"&gt;" is a Nasdaq stock"&lt;/SPAN&gt;);

&lt;SPAN style="COLOR: #2b91af"&gt;Assert&lt;/SPAN&gt;.AreEqual(&lt;SPAN style="COLOR: #a31515"&gt;"msft is a Nasdaq stock"&lt;/SPAN&gt;, r);&lt;/PRE&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Or against sequences:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;i1 = &lt;SPAN style="COLOR: blue"&gt;new int&lt;/SPAN&gt;[] { 1, 2, 3, 4, 5, 6, 7 };

&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;r1 = &lt;SPAN style="COLOR: #2b91af"&gt;F&lt;/SPAN&gt;.Match(i1,
                s =&amp;gt; s.SequenceEqual(&lt;SPAN style="COLOR: blue"&gt;new int&lt;/SPAN&gt;[] { 1, 2}),    &lt;BR&gt;                       s =&amp;gt; s.Where(i =&amp;gt; i &amp;lt; 4),
                s =&amp;gt; s.First() == 2,                        &lt;BR&gt;                       s =&amp;gt; s.Where(i =&amp;gt; i == 1),
                s =&amp;gt; s.Last() == 6,                         &lt;BR&gt;                       s =&amp;gt; s.Select(i =&amp;gt; i * i),
                s =&amp;gt; &lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;,                                  &lt;BR&gt;                       s =&amp;gt; s.Where(i =&amp;gt; i &amp;lt; 7));

&lt;SPAN style="COLOR: #2b91af"&gt;Assert&lt;/SPAN&gt;.IsTrue(i1.Take(6).SequenceEqual(r1));&lt;/PRE&gt;
&lt;P&gt;The match operator, as I defined it, is very flexible (probably too flexible as it doesn't use the type system to enforce much).&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;How it is implemented&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Let's start from the special &lt;EM&gt;match&lt;/EM&gt; against union types: the one that is beautiful but flawed. Its implementation looks just like this (I just show the two parameters version):&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;R Match&amp;lt;T1, T2, R&amp;gt;(&lt;BR&gt;                           &lt;SPAN style="COLOR: blue"&gt;this &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;TypeUnion&lt;/SPAN&gt;&amp;lt;T1, T2&amp;gt; u,&lt;BR&gt;                           &lt;SPAN style="COLOR: #2b91af"&gt;Func&lt;/SPAN&gt;&amp;lt;T1, R&amp;gt; f1, &lt;SPAN style="COLOR: #2b91af"&gt;Func&lt;/SPAN&gt;&amp;lt;T2, R&amp;gt; f2) {

    &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(u.Is&amp;lt;T1&amp;gt;()) &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;f1(u.As&amp;lt;T1&amp;gt;());
    &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(u.Is&amp;lt;T2&amp;gt;()) &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;f2(u.As&amp;lt;T2&amp;gt;());

    &lt;SPAN style="COLOR: blue"&gt;throw new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Exception&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"No Match for this Union Type"&lt;/SPAN&gt;);
}&lt;/PRE&gt;
&lt;P&gt;It is easy to see the reason for the limitations of this function. The same thing that gives you type inference (nice to look at) also gives you the problem with the ordering of lambdas. Also note the I originally intended to have these as extension methods. In practice I ended up liking more the "F.Match" syntax. De gustibus I assume ...&lt;/P&gt;
&lt;P&gt;The more general version looks like this:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;R Match&amp;lt;T, R&amp;gt;(&lt;SPAN style="COLOR: blue"&gt;this &lt;/SPAN&gt;T t,
    &lt;SPAN style="COLOR: #2b91af"&gt;Func&lt;/SPAN&gt;&amp;lt;T, &lt;SPAN style="COLOR: blue"&gt;bool&lt;/SPAN&gt;&amp;gt; match1, &lt;SPAN style="COLOR: #2b91af"&gt;Func&lt;/SPAN&gt;&amp;lt;T, R&amp;gt; func1,
    &lt;SPAN style="COLOR: #2b91af"&gt;Func&lt;/SPAN&gt;&amp;lt;T, &lt;SPAN style="COLOR: blue"&gt;bool&lt;/SPAN&gt;&amp;gt; match2, &lt;SPAN style="COLOR: #2b91af"&gt;Func&lt;/SPAN&gt;&amp;lt;T, R&amp;gt; func2) {

    &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(match1(t))
        &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;func1(t);
    &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(match2(t))
        &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;func2(t);

    &lt;SPAN style="COLOR: blue"&gt;throw new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Exception&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"Nothing matches"&lt;/SPAN&gt;);
}&lt;/PRE&gt;
&lt;P&gt;Again, it is easy to see in the implementation that this is an extremely general thing: a glorified case statement really. This is the beauty of it (you can match against anything) and the ugliness of it (you can write anything as &lt;EM&gt;match1&lt;/EM&gt; of &lt;EM&gt;func1&lt;/EM&gt;, even code that doesn't reference &lt;EM&gt;t&lt;/EM&gt; at all).&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;How to use this series to learn functional programming&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Here is how I did it (it worked for me). Take this library and force yourself to write a medium size program using &lt;U&gt;just&lt;/U&gt; these constructs.&lt;/P&gt;
&lt;P&gt;I mean it. No objects, just records. No inheritance, just discriminated unions. Tuples to return values. Match operators everywhere. No iteration statements (for, while, etc...), just recursion. Extensive use of sequence operators. After a while I noticed that all my functions had the same pattern: they just match against the input and produce an output, usually by calling other functions or recursively calling themselves.&lt;/P&gt;
&lt;P&gt;Obviously, this is overcompensating. After a while you will realize the different trade offs that come with a functional vs OO style of programming. At that point you'll be able to get the best of the two. Or maybe you'll be royally confused ...&lt;/P&gt;
&lt;P&gt;At that point I picked up F# and I'm now enjoying the fact that all these constructs are directly embedded in the language (and yes, you can use while statements too).&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8732828" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category></item><item><title>A C# library to write functional code - Part IV - Type Unions</title><link>http://blogs.msdn.com/lucabol/archive/2008/06/06/a-c-library-to-write-functional-code-part-iv-type-unions.aspx</link><pubDate>Fri, 06 Jun 2008 11:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8577265</guid><dc:creator>lucabol</dc:creator><slash:comments>10</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/8577265.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=8577265</wfw:commentRss><description>&lt;P&gt;Other posts in the series:&lt;/P&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/04/01/a-c-library-to-write-functional-code-part-i-background.aspx"&gt;&lt;STRONG&gt;&lt;FONT color=#006bad&gt;Part I - Background&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx"&gt;&lt;STRONG&gt;&lt;FONT color=#006bad&gt;Part II - Tuples&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt; 
&lt;LI&gt;&lt;STRONG&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/04/21/a-c-library-to-write-functional-code-part-iii-records.aspx"&gt;&lt;FONT color=#006bad&gt;Part III - Records&lt;/FONT&gt;&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A class="" href="http://blogs.msdn.com/lucabol/archive/2008/06/06/a-c-library-to-write-functional-code-part-iv-type-unions.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2008/06/06/a-c-library-to-write-functional-code-part-iv-type-unions.aspx"&gt;Part IV - Type Unions&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A class="" href="http://blogs.msdn.com/lucabol/archive/2008/07/15/a-c-library-to-write-functional-code-part-v-the-match-operator.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2008/07/15/a-c-library-to-write-functional-code-part-v-the-match-operator.aspx"&gt;Part V - The Match operator&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;P&gt;I'm sorry for my prolonged absence in the middle of this series of posts. I'm on a long paternity leave in Italy (playing beach volley every day). It's hard to have the discipline ...&lt;/P&gt;
&lt;P&gt;A bunch of you wrote telling me to finish this. So here I go: let's talk about type unions. First of all: they are not called like that. The correct name is discriminated unions. I have no idea why I call them differently, but I want to be consistent with my previous mistake.&lt;/P&gt;
&lt;P&gt;For those of you with a C++ background (like myself) they are like unions, just better (or worse depending on your convictions). They let you define a type that can represent one of several different types. You can then use the 'match' operator (discussed in the next post) to pattern match against it.&lt;/P&gt;
&lt;P&gt;I won't elaborate on the pros and cons of this style of programming versus using polymorphism. I just want to show you how I implemented this construct in C#. As always, my usual caveat: this is just 'educational code', use it at your own risk, no extensive or perf related test has been done on it. You can download the zip file and check my unit tests for yourself.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;How type unions are used&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;In my world, you declare a type union like this:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Person &lt;/SPAN&gt;{ }
&lt;SPAN style="COLOR: blue"&gt;public class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Dog &lt;/SPAN&gt;{ }

&lt;SPAN style="COLOR: blue"&gt;public class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Friend &lt;/SPAN&gt;: &lt;SPAN style="COLOR: #2b91af"&gt;TypeUnion&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Person&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #2b91af"&gt;Dog&lt;/SPAN&gt;&amp;gt; {

    &lt;SPAN style="COLOR: blue"&gt;public &lt;/SPAN&gt;Friend(&lt;SPAN style="COLOR: #2b91af"&gt;Person &lt;/SPAN&gt;p) : &lt;SPAN style="COLOR: blue"&gt;base&lt;/SPAN&gt;(p) { }
    &lt;SPAN style="COLOR: blue"&gt;public &lt;/SPAN&gt;Friend(&lt;SPAN style="COLOR: #2b91af"&gt;Dog &lt;/SPAN&gt;d) : &lt;SPAN style="COLOR: blue"&gt;base&lt;/SPAN&gt;(d) { }
}&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;You inherit a type union from the "TypeUnion" class and use generic parameters that correspond to the types that the union can represent.&lt;/P&gt;
&lt;P&gt;You can then create a type union as:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;fr = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Friend&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Dog&lt;/SPAN&gt;());&lt;/PRE&gt;
&lt;P&gt;Test its type by:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Assert&lt;/SPAN&gt;.IsTrue(fr.Is&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Dog&lt;/SPAN&gt;&amp;gt;());
&lt;SPAN style="COLOR: #2b91af"&gt;Assert&lt;/SPAN&gt;.IsFalse(fr.Is&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Person&lt;/SPAN&gt;&amp;gt;());&lt;/PRE&gt;
&lt;P&gt;Cast it to one of the types they represent:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;d = fr.As&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Dog&lt;/SPAN&gt;&amp;gt;();&lt;/PRE&gt;
&lt;P&gt;Or use it with the 'match' operator (fully explained in an upcoming post):&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;r = &lt;SPAN style="COLOR: #2b91af"&gt;F&lt;/SPAN&gt;.Match(fr,
    f =&amp;gt; f.Is&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Dog&lt;/SPAN&gt;&amp;gt;(), f =&amp;gt; f.As&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Dog&lt;/SPAN&gt;&amp;gt;().ToString(),
    f =&amp;gt; f.Is&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Person&lt;/SPAN&gt;&amp;gt;(), f =&amp;gt; f.As&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Person&lt;/SPAN&gt;&amp;gt;().ToString());

&lt;SPAN style="COLOR: #2b91af"&gt;Assert&lt;/SPAN&gt;.AreEqual(r, &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Dog&lt;/SPAN&gt;().ToString());&lt;/PRE&gt;
&lt;P&gt;Or the slightly more pleasing:&lt;/P&gt;&lt;PRE class=code&gt;r = &lt;SPAN style="COLOR: #2b91af"&gt;F&lt;/SPAN&gt;.Match(fr,
            (&lt;SPAN style="COLOR: #2b91af"&gt;Person &lt;/SPAN&gt;p) =&amp;gt; p.ToString(),
            (&lt;SPAN style="COLOR: #2b91af"&gt;Dog &lt;/SPAN&gt;d) =&amp;gt; d.ToString());

&lt;SPAN style="COLOR: #2b91af"&gt;Assert&lt;/SPAN&gt;.AreEqual(r, &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Dog&lt;/SPAN&gt;().ToString());&lt;/PRE&gt;
&lt;P&gt;You get the idea.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;How they are implemented&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Nothing really sophisticated going on here. Let's take as an example a type union that can represent two types. I have versions that go to 5 types in the zip file.&lt;/P&gt;
&lt;P&gt;First of all a TypeUnion is a Record:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;TypeUnion&lt;/SPAN&gt;&amp;lt;T1, T2&amp;gt; : &lt;SPAN style="COLOR: #2b91af"&gt;Record&lt;/SPAN&gt;&amp;lt;T1, T2&amp;gt; {&lt;/PRE&gt;
&lt;P&gt;It has overloaded constructors to create a type union of a particular type:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public &lt;/SPAN&gt;TypeUnion(T1 t1)
    : &lt;SPAN style="COLOR: blue"&gt;base&lt;/SPAN&gt;(t1, &lt;SPAN style="COLOR: blue"&gt;default&lt;/SPAN&gt;(T2)) {

    UnionType = t1.GetType();
}
&lt;SPAN style="COLOR: blue"&gt;public &lt;/SPAN&gt;TypeUnion(T2 t2)
    : &lt;SPAN style="COLOR: blue"&gt;base&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;default&lt;/SPAN&gt;(T1), t2) {

    UnionType = t2.GetType();
}&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;UnionType is used to 'remember' which type it is:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;protected &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Type &lt;/SPAN&gt;UnionType;&lt;/PRE&gt;
&lt;P&gt;It also has properties to return the objects of all the types that can be stored:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;protected &lt;/SPAN&gt;T1 Type1 { &lt;SPAN style="COLOR: blue"&gt;get &lt;/SPAN&gt;{ &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;state.Item1; } }
&lt;SPAN style="COLOR: blue"&gt;protected &lt;/SPAN&gt;T2 Type2 { &lt;SPAN style="COLOR: blue"&gt;get &lt;/SPAN&gt;{ &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;state.Item2; } }&lt;/PRE&gt;
&lt;P&gt;The 'Is' operator is simply implemented as:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public bool &lt;/SPAN&gt;Is&amp;lt;K&amp;gt;() {

    &lt;SPAN style="COLOR: blue"&gt;return typeof&lt;/SPAN&gt;(K).IsAssignableFrom(UnionType);
}&lt;/PRE&gt;
&lt;P&gt;And the 'As' operator looks like so:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public &lt;/SPAN&gt;K As&amp;lt;K&amp;gt;() {

    &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(!Is&amp;lt;K&amp;gt;())
        &lt;SPAN style="COLOR: blue"&gt;throw new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Exception&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;.Format(&lt;BR&gt;          &lt;SPAN style="COLOR: #a31515"&gt;"In a TypeUnion cannot cast from {0} to {1}"&lt;/SPAN&gt;,&lt;BR&gt;          UnionType.Name, &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(K).Name));

    &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(T1) == UnionType)
        &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;(K)(&lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt;) Type1;
    &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(T2) == UnionType)
        &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;(K)(&lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt;) Type2;

    &lt;SPAN style="COLOR: blue"&gt;throw new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Exception&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"Shouldn't get here"&lt;/SPAN&gt;);
}&lt;/PRE&gt;
&lt;P&gt;I leave as an exercise to the reader to understand what happens if T1 and T2 are the same type or inherit from the same type. I could have written code to handle this case in a more explicit manner, but didn't.&lt;/P&gt;
&lt;P&gt;Also, by reviewing my code I found an obvious bug in my Is&amp;lt;K&amp;gt;/As&amp;lt;K&amp;gt; code. I fixed it and re-posted the zip file in the second post of this series.&lt;/P&gt;
&lt;P&gt;Now back to the beach. Next post is on the 'match' operator.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8577265" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category></item><item><title>A C# library to write functional code - Part III - Records</title><link>http://blogs.msdn.com/lucabol/archive/2008/04/21/a-c-library-to-write-functional-code-part-iii-records.aspx</link><pubDate>Mon, 21 Apr 2008 20:34:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8415052</guid><dc:creator>lucabol</dc:creator><slash:comments>13</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/8415052.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=8415052</wfw:commentRss><description>&lt;P&gt;Other posts in the series:&lt;/P&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/04/01/a-c-library-to-write-functional-code-part-i-background.aspx"&gt;&lt;STRONG&gt;&lt;FONT color=#006bad&gt;Part I - Background&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx"&gt;&lt;STRONG&gt;&lt;FONT color=#006bad&gt;Part II - Tuples&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt; 
&lt;LI&gt;&lt;STRONG&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/04/21/a-c-library-to-write-functional-code-part-iii-records.aspx"&gt;&lt;FONT color=#006bad&gt;Part III - Records&lt;/FONT&gt;&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A class="" href="http://blogs.msdn.com/lucabol/archive/2008/06/06/a-c-library-to-write-functional-code-part-iv-type-unions.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2008/06/06/a-c-library-to-write-functional-code-part-iv-type-unions.aspx"&gt;Part IV - Type Unions&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A class="" href="http://blogs.msdn.com/lucabol/archive/2008/07/15/a-c-library-to-write-functional-code-part-v-the-match-operator.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2008/07/15/a-c-library-to-write-functional-code-part-v-the-match-operator.aspx"&gt;Part V - The Match operator&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;P&gt;Now that we know what Tuples are, we can start talking about Record, as they use a derivative of Tuples under the cover. But first, what is a record?&lt;/P&gt;
&lt;P&gt;Well, in C# parlance a Record is a&amp;nbsp;sort of&amp;nbsp;immutable value object. I talked at length about these fellows in &lt;A href="http://blogs.msdn.com/lucabol/archive/2007/12/03/creating-an-immutable-value-object-in-c-part-i-using-a-class.aspx" target=_blank mce_href="http://blogs.msdn.com/lucabol/archive/2007/12/03/creating-an-immutable-value-object-in-c-part-i-using-a-class.aspx"&gt;&lt;STRONG&gt;&lt;FONT color=#006bad&gt;this series of blog posts&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt;. In functional parlance, a Record is a Tuple that lets you access its items by name.&lt;/P&gt;
&lt;P&gt;You code Records like this:&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Order&lt;/SPAN&gt;: &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Record&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt;&amp;gt; {

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; Order(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt; item, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; qty): &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;base&lt;/SPAN&gt;(item,qty) {}

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt; Item { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;get&lt;/SPAN&gt; { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; state.Item1;}}
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; Quantity { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;get&lt;/SPAN&gt; { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; state.Item2; } }
    }

    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Customer&lt;/SPAN&gt;: &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Record&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Order&lt;/SPAN&gt;&amp;gt;&amp;gt; {

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; Customer(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt; name, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Order&lt;/SPAN&gt;&amp;gt; orders) : &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;base&lt;/SPAN&gt;(name, orders) { }

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt; Name { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;get&lt;/SPAN&gt; { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; state.Item1; } }
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Order&lt;/SPAN&gt;&amp;gt; Orders { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;get&lt;/SPAN&gt; { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; state.Item2; } }
    }&lt;/PRE&gt;
&lt;P&gt;You need to do three things:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Inherit from a generic Record class specifying the types&amp;nbsp;of the properties as parameters&lt;/LI&gt;
&lt;LI&gt;Add a constructor that calls back to the&amp;nbsp;Record constructor&lt;/LI&gt;
&lt;LI&gt;Add getters to retrieve the values of the properties (no setters as it is immutable)&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;This may seem like plenty of work, but in return you get structural equality. Coding that by hand every time you use a record would be a royal pain. You lose control of the base class, but that is often not a problem as in functional-land you more often use type unions than inheritance.&lt;/P&gt;
&lt;P&gt;How is it implemented?&lt;/P&gt;
&lt;P&gt;First of all it is an abstract class with as many generic parameters as properties that you need in your Record. Let's use two as an example.&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;abstract&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Record&lt;/SPAN&gt;&amp;lt;T1, T2&amp;gt; {
&lt;/PRE&gt;
&lt;P&gt;This abstract class has a field of type STuple:&lt;/P&gt;&lt;PRE class=code&gt;        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;protected&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;readonly&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;STuple&lt;/SPAN&gt;&amp;lt;T1, T2&amp;gt; state;
&lt;/PRE&gt;
&lt;P&gt;What is a STuple? Well it is exactly the same as the Tuple described in Part II, but coded as a struct instead of a class. The reason to use a struct is to not allocate an additional object on the stack. This allows this solution to be as 'performant' as simply having coded the fields on the class itself. Or at least I think so ...&lt;/P&gt;
&lt;P&gt;The Record class also has a constructor that simply initialize the STuple:&lt;/P&gt;&lt;PRE class=code&gt;        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; Record(T1 t1, T2 t2) { state = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;F&lt;/SPAN&gt;.STuple(t1, t2); }&lt;/PRE&gt;&lt;PRE class=code&gt;&lt;FONT face=Verdana&gt;where&lt;/FONT&gt;&lt;/PRE&gt;&lt;PRE class=code&gt;        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;internal&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;STuple&lt;/SPAN&gt;&amp;lt;T1, T2&amp;gt; STuple&amp;lt;T1, T2&amp;gt;(T1 t1, T2 t2) {

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;STuple&lt;/SPAN&gt;&amp;lt;T1, T2&amp;gt;(t1, t2);
        }&lt;/PRE&gt;
&lt;P&gt;The Equals method is very much the same as the Tuple's one, just delegating to the same DSEqual function that checks equality for Tuples.&lt;/P&gt;&lt;PRE class=code&gt;        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;bool&lt;/SPAN&gt; Equals(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;object&lt;/SPAN&gt; right) {

            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Utils&lt;/SPAN&gt;.CheckNull(right);

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;object&lt;/SPAN&gt;.ReferenceEquals(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;this&lt;/SPAN&gt;, right))
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;true&lt;/SPAN&gt;;

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;this&lt;/SPAN&gt;.GetType() != right.GetType())
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;false&lt;/SPAN&gt;;

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; rightT = right &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;as&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Record&lt;/SPAN&gt;&amp;lt;T1, T2&amp;gt;;

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;F&lt;/SPAN&gt;.DSEquals(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;this&lt;/SPAN&gt;.state, rightT.state);
        }&lt;/PRE&gt;That's it. Not too difficult as most of the implementation is based on the Tuple's code. Next post will hopefully be more interesting. It is about Type Unions.&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8415052" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category></item><item><title>A C# library to write functional code - Part II - Tuples</title><link>http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx</link><pubDate>Tue, 08 Apr 2008 23:51:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8369978</guid><dc:creator>lucabol</dc:creator><slash:comments>16</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/8369978.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=8369978</wfw:commentRss><description>&lt;P&gt;Other posts in the series:&lt;/P&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/04/01/a-c-library-to-write-functional-code-part-i-background.aspx"&gt;&lt;STRONG&gt;&lt;FONT color=#006bad&gt;Part I - Background&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx"&gt;&lt;STRONG&gt;&lt;FONT color=#006bad&gt;Part II - Tuples&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt; 
&lt;LI&gt;&lt;STRONG&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/04/21/a-c-library-to-write-functional-code-part-iii-records.aspx"&gt;&lt;FONT color=#006bad&gt;Part III - Records&lt;/FONT&gt;&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A class="" href="http://blogs.msdn.com/lucabol/archive/2008/06/06/a-c-library-to-write-functional-code-part-iv-type-unions.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2008/06/06/a-c-library-to-write-functional-code-part-iv-type-unions.aspx"&gt;Part IV - Type Unions&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A class="" href="http://blogs.msdn.com/lucabol/archive/2008/07/15/a-c-library-to-write-functional-code-part-v-the-match-operator.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2008/07/15/a-c-library-to-write-functional-code-part-v-the-match-operator.aspx"&gt;Part V - The Match operator&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;P&gt;&lt;A href="http://en.wikipedia.org/wiki/Tuple" target=_blank mce_href="http://en.wikipedia.org/wiki/Tuple"&gt;&lt;STRONG&gt;&lt;FONT color=#006bad&gt;Tuples&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt; are a way for you not to name things. In Object Oriented languages&amp;nbsp;you got to name everything. If you need to represent a bunch of data, you create a class for it.&lt;/P&gt;
&lt;P&gt;There is a strange asymmetry in mainstream OO languages in that you can pass multiple parameters to a function, but you can return just one value. Granted, there are ways around it: you can use 'ref' in C# or return some sort of collection where things are stored. But by and large the model is: you pass many, you get one; if you need to return more than one, create a class to represent this 'bunch of data'. Tuples are a way for you not to create such a class.&lt;/P&gt;
&lt;P&gt;Tuples are also much more than that. Once you have&amp;nbsp;the language&amp;nbsp;concept of 'a bunch of data without a name', you can create arrays of them, you can pass them as parameters, use them as local variables. Wherever you'd use a type, you can use a Tuple instead.&lt;/P&gt;
&lt;P&gt;This is particularly appealing to me as I like to use classes almost exclusively to represent things that have a counterpart in the domain I'm modeling (i.e. Customer, Account). I don't like to create classes/structs just for the sake of temporarily put some data together.&lt;/P&gt;
&lt;P&gt;You can create&amp;nbsp;your own Tuple class&amp;nbsp;in C#, but the syntax gets ugly. Syntax matter. Syntax helps you to think differently about your program. We have syntax for anonymous types, but given that they cannot escape the scope of a method, they cannot be used as full replacement for Tuples.&lt;/P&gt;
&lt;P&gt;In any case, to my implementation. Here is how you create a Tuple:&lt;/P&gt;&lt;PRE class=code&gt;            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; t1 = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;F&lt;/SPAN&gt;.Tuple(34, &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"bo"&lt;/SPAN&gt;, 2.3);&lt;/PRE&gt;
&lt;P&gt;not too bad. In F# it is better: (34, "bo", 2.3). And you often don't need the parenthesis. But still, my C# version is ok.&lt;/P&gt;
&lt;P&gt;You then need to access its elements:&lt;/P&gt;&lt;PRE class=code&gt;            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; n = t1.Item1;
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; s = t1.Item2;
&lt;/PRE&gt;
&lt;P&gt;In F# you usually access them by doing pattern matching, which gives a more intuitive syntax. But again, my C# syntax is not terrible.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Tuples need to have structural equality, which means that the following has to work:&lt;/P&gt;&lt;PRE class=code&gt;        &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ArrayList&lt;/SPAN&gt; mad1 = &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ArrayList&lt;/SPAN&gt; { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;List&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt;&amp;gt;&amp;gt; { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt;[] { &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"bo"&lt;/SPAN&gt; }, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt;[] { &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"bo"&lt;/SPAN&gt; } },&lt;BR&gt;                               32, &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"bo"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt;[] { 4, 5, 6 } };
        &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ArrayList&lt;/SPAN&gt; mad2 = &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ArrayList&lt;/SPAN&gt; { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;List&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt;&amp;gt;&amp;gt; { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt;[] { &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"bo"&lt;/SPAN&gt; }, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt;[] { &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"bo"&lt;/SPAN&gt; } },&lt;BR&gt;                               32, &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"bo"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt;[] { 4, 5, 6 } };
        &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ArrayList&lt;/SPAN&gt; mad3 = &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ArrayList&lt;/SPAN&gt; { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;List&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt;&amp;gt;&amp;gt; { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt;[] { &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"bo"&lt;/SPAN&gt; }, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt;[] { &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"bo"&lt;/SPAN&gt; } },&lt;BR&gt;                               32, &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"bo"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt;[] { 4, 5, 5 } };&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;PRE class=code&gt;        &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreEqual(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;F&lt;/SPAN&gt;.Tuple(mad1, mad2, mad1), &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;F&lt;/SPAN&gt;.Tuple(mad2, mad1, mad2));
        &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreNotEqual(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;F&lt;/SPAN&gt;.Tuple(mad1, mad2, mad1), &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;F&lt;/SPAN&gt;.Tuple(mad1, mad3, mad1));&lt;/PRE&gt;
&lt;P&gt;You can use Tuples as return values, parameters, locals etc. Unfortunately, the syntax is ugly when Tuples are part of the signature of a function:&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Tuple&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Tuple&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ObservationHistory&lt;/SPAN&gt;&amp;gt;&amp;gt;&amp;gt; Execute() {

    }&lt;/PRE&gt;
&lt;P&gt;With the above information, you can be a user of Tuples. From this point on, I'll talk about some details of the implementation (I also attach the full code to this post as a zip file).&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Tuple&lt;/SPAN&gt;&amp;lt;T1&amp;gt; {

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; Tuple(T1 t1) {

            Item1 = t1;
        }

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;readonly&lt;/SPAN&gt; T1 Item1;

&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;       &lt;FONT color=#80ff80&gt; &lt;/FONT&gt;&lt;FONT color=#808080&gt;#region&lt;/FONT&gt;&lt;/SPAN&gt;&lt;FONT color=#808080&gt; Equals, GetHashCode, ==, !=&lt;/FONT&gt;
    }

    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Tuple&lt;/SPAN&gt;&amp;lt;T1, T2&amp;gt; : &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Tuple&lt;/SPAN&gt;&amp;lt;T1&amp;gt; {

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; Tuple(T1 t1, T2 t2) : &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;base&lt;/SPAN&gt;(t1) { Item2 = t2; }

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;readonly&lt;/SPAN&gt; T2 Item2;

&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;        &lt;FONT color=#808080&gt;#region&lt;/FONT&gt;&lt;/SPAN&gt;&lt;FONT color=#808080&gt; Equals, GetHashCode, ==, !=
&lt;/FONT&gt;    }&lt;/PRE&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;So, Tuples are classes, not structs. The reason for it is fully described in &lt;A href="http://blogs.msdn.com/lucabol/archive/2008/01/11/creating-an-immutable-value-object-in-c-part-v-using-a-library.aspx" target=_blank mce_href="http://blogs.msdn.com/lucabol/archive/2008/01/11/creating-an-immutable-value-object-in-c-part-v-using-a-library.aspx"&gt;&lt;STRONG&gt;&lt;FONT color=#006bad&gt;this series of posts&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt;. They also inherit from one another. There are pros and cons to that. The main pros are that I had to write less code and that you can pass a Tuple&amp;lt;int, string&amp;gt; when a function expects a Tuple&amp;lt;int, string, int&amp;gt;. The main drawback is that you can pass a Tuple&amp;lt;int, string&amp;gt; when a function expects a Tuple&amp;lt;int, string, int&amp;gt;.&amp;nbsp; Also notice the use of public fields. These&amp;nbsp;is a problem with frameworks that insist on properties (i.e. Data Binding). Also, I just got to 5 as arity goes. The day I need 6 items, I'll add another one. It is boilerplate code (that I'd still like not to write).&lt;/P&gt;
&lt;P&gt;The Equals method is a bit convoluted:&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;internal&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Utils&lt;/SPAN&gt; {

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;void&lt;/SPAN&gt; CheckNull&amp;lt;T&amp;gt;(T t) {

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (t == &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;null&lt;/SPAN&gt;)
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;ArgumentNullException&lt;/SPAN&gt;();
        }&lt;BR&gt;     }&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;PRE class=code&gt;       &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;bool&lt;/SPAN&gt; Equals(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;object&lt;/SPAN&gt; right) {

            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Utils&lt;/SPAN&gt;.CheckNull(right);

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;object&lt;/SPAN&gt;.ReferenceEquals(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;this&lt;/SPAN&gt;, right))
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;true&lt;/SPAN&gt;;

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;this&lt;/SPAN&gt;.GetType() != right.GetType())
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;false&lt;/SPAN&gt;;

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; rightT = right &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;as&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Tuple&lt;/SPAN&gt;&amp;lt;T1, T2, T3&amp;gt;;

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;base&lt;/SPAN&gt;.Equals(rightT) &amp;amp;&amp;amp; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;F&lt;/SPAN&gt;.DSEquals(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;this&lt;/SPAN&gt;.Item3, rightT.Item3);
        }&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;I always get complaints when I show Equals methods that throw if null is passed in, but I stand by my logic, that&amp;nbsp;the presence of null for these categories of&amp;nbsp;'structurally equal' classes is symptom of an error and I want to be notified.&amp;nbsp;Returning false doesn't do that.&lt;/P&gt;&lt;PRE class=code&gt;        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;internal&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;bool&lt;/SPAN&gt; DSEquals&amp;lt;T&amp;gt;(T left, T right) {

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (left == &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;null&lt;/SPAN&gt; &amp;amp;&amp;amp; right == &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;null&lt;/SPAN&gt;)
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;true&lt;/SPAN&gt;;

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (left == &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;null&lt;/SPAN&gt; &amp;amp;&amp;amp; right != &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;null&lt;/SPAN&gt;)
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;false&lt;/SPAN&gt;;

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; len = left &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;as&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;;
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; ren = right &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;as&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;;

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (len == &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;null&lt;/SPAN&gt; &amp;amp;&amp;amp; ren == &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;null&lt;/SPAN&gt;)
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; left.Equals(right);

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (len == &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;null&lt;/SPAN&gt; &amp;amp;&amp;amp; ren != &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;null&lt;/SPAN&gt;)
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;false&lt;/SPAN&gt;;

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (len != &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;null&lt;/SPAN&gt; &amp;amp;&amp;amp; ren == &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;null&lt;/SPAN&gt;)
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;false&lt;/SPAN&gt;;

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; SequenceEqual(len, ren);
        }&lt;/PRE&gt;
&lt;P&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;DSEquals check the content of the Tuple and forward to SequenceEqual in case one slot of the Tuple contains an IEnumerable.&lt;/P&gt;&lt;PRE class=code&gt;        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;internal&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;bool&lt;/SPAN&gt; SequenceEqual(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt; en1, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt; en2) {

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; enumerator = en2.GetEnumerator();
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;foreach&lt;/SPAN&gt; (&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; o &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;in&lt;/SPAN&gt; en1) {

                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (!enumerator.MoveNext())
                    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;false&lt;/SPAN&gt;;

                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (!DSEquals(o, enumerator.Current))
                    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;false&lt;/SPAN&gt;;
            }
&lt;/PRE&gt;
&lt;P&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;SequenceEqual checks that the number of items in the enumerator is the same and recursively calls DSEqual to check structural equality for items at the same index in the two enumerators.&lt;/P&gt;
&lt;P&gt;GetHashCode is trivial (and maybe trivially wrong, one of these days I'll learn everything about GetHashCode() ).&lt;/P&gt;&lt;PRE class=code&gt;        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; GetHashCode() {

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;base&lt;/SPAN&gt;.GetHashCode() | Item3.GetHashCode();
        }&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;The equality operators are equally simple.&lt;/P&gt;&lt;PRE class=code&gt;        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;bool&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;operator&lt;/SPAN&gt; ==(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Tuple&lt;/SPAN&gt;&amp;lt;T1, T2, T3&amp;gt; t1, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Tuple&lt;/SPAN&gt;&amp;lt;T1, T2, T3&amp;gt; t2) {

            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Utils&lt;/SPAN&gt;.CheckNull(t1);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Utils&lt;/SPAN&gt;.CheckNull(t2);

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; t1.Equals(t2);
        }
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;bool&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;operator&lt;/SPAN&gt; !=(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Tuple&lt;/SPAN&gt;&amp;lt;T1, T2, T3&amp;gt; t1, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Tuple&lt;/SPAN&gt;&amp;lt;T1, T2, T3&amp;gt; t2) {

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; !(t1 == t2);
        }&lt;/PRE&gt;
&lt;P&gt;And ToString() prints my favorite Tuple format.&lt;/P&gt;&lt;PRE class=code&gt;        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt; ToString() {

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt;.Format(&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"{0},{1}"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;base&lt;/SPAN&gt;.ToString(), Item3.ToString());
        }&lt;/PRE&gt;
&lt;P&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;I'm sure you can find plenty of issues in this code. As always, it is not 'production ready', it is more 'Luca having fun doing it'. In any case, there are some testcases in the solution to check the extent of my testing.&lt;/P&gt;
&lt;P&gt;In the next post we'll look at Records.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8369978" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/lucabol/attachment/8369978.ashx" length="1535926" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category></item><item><title>A C# library to write functional code - Part I - Background</title><link>http://blogs.msdn.com/lucabol/archive/2008/04/01/a-c-library-to-write-functional-code-part-i-background.aspx</link><pubDate>Tue, 01 Apr 2008 20:36:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8348521</guid><dc:creator>lucabol</dc:creator><slash:comments>15</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/8348521.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=8348521</wfw:commentRss><description>&lt;P&gt;Other posts in the series:&lt;/P&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/04/01/a-c-library-to-write-functional-code-part-i-background.aspx"&gt;&lt;STRONG&gt;&lt;FONT color=#006bad&gt;Part I - Background&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/04/08/a-c-library-to-write-functional-code-part-ii-tuples.aspx"&gt;&lt;STRONG&gt;&lt;FONT color=#006bad&gt;Part II - Tuples&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt; 
&lt;LI&gt;&lt;STRONG&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2008/04/21/a-c-library-to-write-functional-code-part-iii-records.aspx"&gt;&lt;FONT color=#006bad&gt;Part III - Records&lt;/FONT&gt;&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A class="" href="http://blogs.msdn.com/lucabol/archive/2008/06/06/a-c-library-to-write-functional-code-part-iv-type-unions.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2008/06/06/a-c-library-to-write-functional-code-part-iv-type-unions.aspx"&gt;Part IV - Type Unions&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A class="" href="http://blogs.msdn.com/lucabol/archive/2008/07/15/a-c-library-to-write-functional-code-part-v-the-match-operator.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2008/07/15/a-c-library-to-write-functional-code-part-v-the-match-operator.aspx"&gt;Part V - The Match operator&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;P&gt;In December (slow time in msft) I decided to understand what functional programming is all about. When I say 'understanding' I don't mean just paying lip service to the main concepts by knowingly mentioning them in casual conversations (i.e. "look at this memoization, man!" or "this lambda function is so hot!". I can already do that. I intellectually know what the thing is.&lt;/P&gt;
&lt;P&gt;I wanted to *really* understand it. For me that means writing plenty of code. I had a medium size application in my mind that I've been wanting to write for quite some time (stock price, dividends, splits downloading and various return calculations), so I went ahead and wrote it. I also wanted to use C#. It would have been easier in F#, but I work on the C# team and love using our own product.&lt;/P&gt;
&lt;P&gt;My early attempts were unpleasing. I would fall back to my OO background and my functional code slowly reverted to OO code. My way of thinking about it, even if starting with the best intentions, would go back to: what are the objects, what are their responsibilities and such.&lt;/P&gt;
&lt;P&gt;I needed to force myself somehow; kind of overcompensate on the other side. I hit on the idea of pragmatically defining functional programming and try to limit myself to the subset of language constructs inside my definition. As a way to define it, I used Chapter 3 of "&lt;A href="http://www.amazon.com/Expert-F-Experts-Voice-Net/dp/1590598504/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1207069956&amp;amp;sr=8-1" target=_blank mce_href="http://www.amazon.com/Expert-F-Experts-Voice-Net/dp/1590598504/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1207069956&amp;amp;sr=8-1"&gt;&lt;STRONG&gt;&lt;FONT color=#006bad&gt;Expert F#&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt;". I know, I know, I could have read 1,000s of academic papers and come up with a meta-analysis of all of them that formally defines what 'functional programming' really is. But life is too short. I trusted Don.&lt;/P&gt;
&lt;P&gt;The problem is, several of the language constructs in my small definition of functional programming don't exist in C#. So I went ahead and created them. I built a little library to represent them and forced myself to write code using just this library. It worked.&lt;/P&gt;
&lt;P&gt;In this series of posts I will describe what's inside this library. I want to emphasize that I built it for educational purpose only, not for performance or production code. Caveat emptor.&lt;/P&gt;
&lt;P&gt;My plan is to cover the following:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Tuples 
&lt;LI&gt;Records 
&lt;LI&gt;Type Unions 
&lt;LI&gt;Match&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Let's see if I can find the time to actually write these posts :-)&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8348521" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category></item><item><title>"LINQ to SQL Overview" video</title><link>http://blogs.msdn.com/lucabol/archive/2008/03/03/linq-to-sql-overview-video.aspx</link><pubDate>Tue, 04 Mar 2008 00:51:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8010761</guid><dc:creator>lucabol</dc:creator><slash:comments>12</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/8010761.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=8010761</wfw:commentRss><description>&lt;P&gt;This is my presentation from TechEd Barcelona: &lt;STRONG&gt;The link has been fixed. It should work now. Let me know if it doesn't.&lt;/STRONG&gt;&amp;nbsp;&lt;A href="http://www.microsoft.com/emea/msdn/spotlight/sessionh.aspx?videoid=716" mce_href="http://www.microsoft.com/emea/msdn/spotlight/sessionh.aspx?videoid=716"&gt;http://www.microsoft.com/emea/msdn/spotlight/sessionh.aspx?videoid=716&lt;/A&gt;. The European locale brings out my Italian accent ...&lt;/P&gt;
&lt;P&gt;&amp;nbsp;On this page there are a bunch of interesting presentations (i.e. Anders on LINQ): &lt;A href="http://www.microsoft.com/emea/msdn/spotlight/default.aspx" mce_href="http://www.microsoft.com/emea/msdn/spotlight/default.aspx"&gt;http://www.microsoft.com/emea/msdn/spotlight/default.aspx&lt;/A&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8010761" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category></item><item><title>Creating an immutable value object in C# - Part V - Using a library</title><link>http://blogs.msdn.com/lucabol/archive/2008/01/11/creating-an-immutable-value-object-in-c-part-v-using-a-library.aspx</link><pubDate>Fri, 11 Jan 2008 21:36:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7077713</guid><dc:creator>lucabol</dc:creator><slash:comments>12</slash:comments><comments>http://blogs.msdn.com/lucabol/comments/7077713.aspx</comments><wfw:commentRss>http://blogs.msdn.com/lucabol/commentrss.aspx?PostID=7077713</wfw:commentRss><description>&lt;P&gt;Other posts: 
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2007/12/03/creating-an-immutable-value-object-in-c-part-i-using-a-class.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2007/12/03/creating-an-immutable-value-object-in-c-part-i-using-a-class.aspx"&gt;Part I - Using a class&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2007/12/06/creating-an-immutable-value-object-in-c-part-ii-making-the-class-better.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2007/12/06/creating-an-immutable-value-object-in-c-part-ii-making-the-class-better.aspx"&gt;Part II - Making the class better&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/archive/2007/12/24/creating-an-immutable-value-object-in-c-part-iii-using-a-struct.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2007/12/24/creating-an-immutable-value-object-in-c-part-iii-using-a-struct.aspx"&gt;Part III - Using a struct&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/lucabol/" mce_href="http://blogs.msdn.com/lucabol/"&gt;Part IV - A class with a special value&lt;/A&gt;&lt;/LI&gt;
&lt;P&gt;In the last post we presented a variation of implementing a value object using a class. Everything works (obviously), but the amount of code to write is unpleasing. In this post we examine a library based solution. I just describe how to use the Record class, not how it is implemented. You can read the attached implementation code (it is in functional.cs). There is much more in there than "Record&amp;lt;...&amp;gt;". I'll talk about the rest in a (hopefully) upcoming series.&lt;/P&gt;
&lt;P&gt;To use the record class you need to inherit from it, as in:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateSpan&lt;/SPAN&gt;: &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Record&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;bool&lt;/SPAN&gt;&amp;gt; {...}&lt;/PRE&gt;
&lt;P&gt;The generic argument types represent the types that comprise the (immutable) state of the object. You then need a friendly way for folks to access this state:&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt; Start { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;get&lt;/SPAN&gt; { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; state.Item1; } }
    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;DateTime&lt;/SPAN&gt; End { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;get&lt;/SPAN&gt; { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; state.Item2; } }
    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;bool&lt;/SPAN&gt; HasValue { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;get&lt;/SPAN&gt; { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; state.Item3; } }
&lt;/PRE&gt;
&lt;P&gt;This is all you have to do. You don't need to implement "Equals", "==", "!=" and "GetHashCode". Structural equivalence is given to you by the Record class. Such a property is recursive, in the sense that you can embed value objects inside other value objects and the implementation would walk your object graph as necessary.&lt;/P&gt;
&lt;P&gt;For example, given the following class hierarchy:&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Order&lt;/SPAN&gt;: &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Record&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt;&amp;gt; {

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; Order(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt; item, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; qty): &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;base&lt;/SPAN&gt;(item,qty) {}

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt; Item { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;get&lt;/SPAN&gt; { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; state.Item1;}}
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; Quantity { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;get&lt;/SPAN&gt; { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; state.Item2; } }
    }

    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Customer&lt;/SPAN&gt;: &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Record&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Order&lt;/SPAN&gt;&amp;gt;&amp;gt; {

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; Customer(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt; name, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Order&lt;/SPAN&gt;&amp;gt; orders) : &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;base&lt;/SPAN&gt;(name, orders) { }

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt; Name { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;get&lt;/SPAN&gt; { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; state.Item1; } }
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Order&lt;/SPAN&gt;&amp;gt; Orders { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;get&lt;/SPAN&gt; { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; state.Item2; } }
    }&lt;/PRE&gt;
&lt;P&gt;The following test case succeed:&lt;/P&gt;&lt;PRE class=code&gt;        [&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;TestMethod&lt;/SPAN&gt;]
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;void&lt;/SPAN&gt; Record2Test() {

            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; c1 = &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Customer&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"Luca"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Order&lt;/SPAN&gt;[] { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Order&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"car"&lt;/SPAN&gt;,1), &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Order&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"stereo"&lt;/SPAN&gt;, 3)});
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; c11 = &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Customer&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"Luca"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Order&lt;/SPAN&gt;[] { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Order&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"car"&lt;/SPAN&gt;, 1), &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Order&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"stereo"&lt;/SPAN&gt;, 3) });
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; c2 = &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Customer&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"Bob"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Order&lt;/SPAN&gt;[] { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Order&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"car"&lt;/SPAN&gt;, 1), &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Order&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"stereo"&lt;/SPAN&gt;, 3) });
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; c3 = &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Customer&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"Bob"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Order&lt;/SPAN&gt;[] { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Order&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"car"&lt;/SPAN&gt;, 1), &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Order&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"stereo"&lt;/SPAN&gt;, 2) });

            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreEqual(c1, c11);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreNotEqual(c1, c2);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreNotEqual(c1, c3);
            &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Assert&lt;/SPAN&gt;.AreNotEqual(c2, c3);

        }&lt;/PRE&gt;
&lt;P&gt;Please don't take my library as production ready code. The amount of test I put into it is limited. You can probably find obvious bugs with it. &lt;/P&gt;
&lt;P&gt;Let's look at other drawbacks. The biggest one is that I'm stealing your base class. If you want your value object to inherit from something else, you cannot. You cannot even have value objects inherit from each other. In that case you are back to implementing your own Equals, == and so on. The only tools at your disposal are interfaces and composition.&lt;/P&gt;
&lt;P&gt;Another drawback is that writing classes in this way is slightly unnatural. You have to think about the 'type' of your state in the declaration of the class itself instead of more naturally writing it closer to where you assign names to it (property/field declaration).&lt;/P&gt;
&lt;P&gt;Having considered these drawbacks, I'm using this library in all my code wherever I need value objects (which is almost everywhere these days). Writing all the "Equals" explicitly is too error prone for my taste. I will also be creating IDE snippets for myself that make writing these classes easier.&lt;/P&gt;
&lt;P&gt;I don't think I have anything else to say on this topic, so this will be my last post on it. If something else comes up, I'll let you know.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7077713" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/lucabol/attachment/7077713.ashx" length="214538" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/lucabol/archive/tags/C_2300_+Programming/default.aspx">C# Programming</category></item></channel></rss>