<?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>Rick Byers : Languages</title><link>http://blogs.msdn.com/rmbyers/archive/tags/Languages/default.aspx</link><description>Tags: Languages</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Using LINQ for Computational Genomics</title><link>http://blogs.msdn.com/rmbyers/archive/2007/05/07/using-linq-for-computational-genomics.aspx</link><pubDate>Tue, 08 May 2007 08:23:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2474445</guid><dc:creator>rmbyers</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/rmbyers/comments/2474445.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rmbyers/commentrss.aspx?PostID=2474445</wfw:commentRss><description>&lt;P mce_keep="true"&gt;I’ve been playing around a bit lately with computational genomics (I’m doing a project for my parallel computation class). I wanted to write some simple algorithms that operate on potentially large amounts of DNA data without using a ton of RAM. For example, the entire human genome is 3 billion base pairs – reading it all into memory is out of the question (at least on my home PC). It occurred to me that this was a perfect opportunity to spend some more time using &lt;A class="" href="http://msdn2.microsoft.com/en-us/netframework/aa904594.aspx" mce_href="http://msdn2.microsoft.com/en-us/netframework/aa904594.aspx"&gt;LINQ&lt;/A&gt;. Computations like this are inherently stream based, and LINQ allows you to express and compose operations on streams very effectively. Here’s a simple example that I hope will help demonstrate the power of LINQ. &lt;/P&gt;
&lt;P&gt;One of the simplest forms of statistical analysis done on a DNA sequence is producing a graph of it’s “GC density”. To a computer scientist, a DNA sequence is just a string of A, C, T, and G characters. The GC density with window size ‘w’ for a sequence is another (similarly sized) sequence of numbers between 0 and 1, each of which represents the ratio of Gs and Cs in the previous ‘w’ characters. For example, for the sequence “ATGCAG”, the GC density with window size 2 is “0, 0.5, 1, 0.5, 0.5”. 
&lt;P&gt;So, in order to calculate this, I first started with a simple function which, given a nucleotide sequence, would return an identical-length sequence of the number of Gs or Cs seen so far:&amp;nbsp; 
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt; 
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; Generate a sequence that is the prefix sum of Gs and Cs in the input sequence.&lt;?xml:namespace prefix = o /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="sequence"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;The input nucleotide sequence&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;returns&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;A sequence of the same length for which each element indicates the&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; count of Gs and Cs between the beginning and corresponding position in&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; the input sequence.&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/returns&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;&amp;gt; GenerateGCCount(&lt;SPAN style="COLOR: #2b91af"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Nucleotide&lt;/SPAN&gt;&amp;gt; sequence)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt; count = 0;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;foreach&lt;/SPAN&gt; (&lt;SPAN style="COLOR: #2b91af"&gt;Nucleotide&lt;/SPAN&gt; n &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; sequence)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (n == &lt;SPAN style="COLOR: #2b91af"&gt;Nucleotide&lt;/SPAN&gt;.G || n == &lt;SPAN style="COLOR: #2b91af"&gt;Nucleotide&lt;/SPAN&gt;.C)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;count++;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;yield&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; count;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Given this sequence (call it s), the density for window size w at some position i could (conceptually) be calculated with the formula d[i] = (s[i+w]-s[i])/w. However, since we might want a large window size, we don’t even necessarily want to have w nucleotides in memory at once, so we can’t use such a simple formula. However, the stream-based version is almost as simple: 
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt; 
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; Compute the GC density of the specified nucleotide sequence.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="sequence"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;The sequence of nucleotides&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="windowSize"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;Size of the window for each density calculation&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;returns&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;A sequence for which each element indicates the ratio of Gs and Cs to&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; total nucleotides over the past windowSize elements&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/returns&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: blue"&gt;float&lt;/SPAN&gt;&amp;gt; ComputeGCDensity(&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Nucleotide&lt;/SPAN&gt;&amp;gt; sequence,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt; windowSize)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (windowSize &amp;lt; 1)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentOutOfRangeException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"windowSize"&lt;/SPAN&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// First compute a sequence of the running count of G or C nucleotides&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; gcCounts = GenerateGCCount(sequence);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// Combine the sequence with a copy of itself offset by the window size&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// The elements of the sequence are pairs of counts, with the first element&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// of the pair being the GC count at the beginning of the window, and the&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// second element of the pair being the GC count at the end of the window.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; gcWindows = gcCounts.Zip(gcCounts.Skip(windowSize - 1));&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// Now for each window, compute the gc density and return it&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; gcWindows.Select(&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;p =&amp;gt; (&lt;SPAN style="COLOR: blue"&gt;float&lt;/SPAN&gt;)(p.Second - p.First) / windowSize);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;This is pretty much it. If you remove the comments this is only a couple lines of code (or a single long query line if you prefer). Zip is just a helper function I wrote (based on list-processing functions in other functional languages like &lt;A class="" href="http://www.standardml.org/Basis/list-pair.html#SIG:LIST_PAIR.zip:VAL" mce_href="http://www.standardml.org/Basis/list-pair.html#SIG:LIST_PAIR.zip:VAL"&gt;standard ML’s ListPair.zip&lt;/A&gt; or &lt;A class="" href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html#VALcombine" mce_href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html#VALcombine"&gt;OCaml’s List.Combine&lt;/A&gt;) that returns a sequence of pairs from the two input sequences: 
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt; 
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; A pair (2-tuple)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;typeparam name="T1"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;Type of the first element&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/typeparam&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;typeparam name="T2"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;Type of the second element&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/typeparam&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;struct&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;Tuple&lt;/SPAN&gt;&amp;lt;T1,T2&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; Tuple(T1 first, T2 second)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;First = first;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Second = second;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;readonly&lt;/SPAN&gt; T1 First;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;readonly&lt;/SPAN&gt; T2 Second;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;summary&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; Combine two sequences into a sequence of pairs&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/summary&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;typeparam name="T1"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;Type of the elements of the first sequence&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/typeparam&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;typeparam name="T2"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;Type of the elements of the second sequence&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/typeparam&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="source1"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;The first sequence&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;param name="source2"&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;The second sequence&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;returns&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;A sequence that is as long as the shorter of source1 and source2.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; Each element is a pair of values - one from each of the input sequences&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; at the same position.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;If the input sequences are of unequal length, any extra&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt; data in the longer list is not used.&lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;&amp;lt;/returns&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Tuple&lt;/SPAN&gt;&amp;lt;T1, T2&amp;gt;&amp;gt; Zip&amp;lt;T1, T2&amp;gt;(&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;T1&amp;gt; source1,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;T2&amp;gt; source2)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// Conceptually we just want to foreach over both sequences, but we must&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// write the code manually since foreach works for only a single sequence&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; enum1 = source1.GetEnumerator();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; enum2 = source2.GetEnumerator();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;while&lt;/SPAN&gt; (enum1.MoveNext() &amp;amp;&amp;amp; enum2.MoveNext())&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;yield&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;Tuple&lt;/SPAN&gt;&amp;lt;T1,T2&amp;gt;(enum1.Current, enum2.Current);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN-CA style="mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&lt;FONT face="Times New Roman" size=3&gt;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Together I think this is pretty simple and elegant. I create two instances of the same sequence, offset one by the window size, and then use their difference to compute the density. All of this is done on demand each time a density value is required. I’m not keeping any information about any position other than the current one in memory at any one time. One drawback is that for small window sizes, it may actually be pretty silly (from a performance perspective) to read each byte of the sequence from the file twice. But I consider this an optimization problem with the operating system file system cache should ideally solve for me. In practice execution still appears to be CPU bound, so I think the OS is doing a good job – the extra I/O isn’t a concern. 
&lt;P&gt;If you’re new to this style of programming, it can sometimes get a little confusing trying to keep track of the timing in which things execute. C#’s &lt;A class="" href="http://msdn.microsoft.com/msdnmag/issues/06/00/C20/default.aspx" mce_href="http://msdn.microsoft.com/msdnmag/issues/06/00/C20/default.aspx"&gt;iterator method&lt;/A&gt; syntax and the IEnumerable pattern in general can make the use of delayed computation a little subtle. This is a big benefit of using a &lt;A class="" href="http://blogs.msdn.com/charlie/archive/2007/01/26/anders-hejlsberg-on-linq-and-functional-programming.aspx" mce_href="http://blogs.msdn.com/charlie/archive/2007/01/26/anders-hejlsberg-on-linq-and-functional-programming.aspx"&gt;functional programming style&lt;/A&gt; like I have where no shared state is modified and the functions have no side-effects. The order in which things execute is unimportant. 
&lt;P&gt;To test that this actually worked on large data sources without using a lot of RAM, I ran it on the entire Human Chromosome 1 sequence (the largest one - almost 300 MB uncompressed) with a window size of 100000. For kicks, I also ran it on the &lt;A class="" href="http://en.wikipedia.org/wiki/Chimpanzee_Genome_Project" mce_href="http://en.wikipedia.org/wiki/Chimpanzee_Genome_Project"&gt;Chimpanzee&lt;/A&gt; chromosome 1. Both runs took about 10 minutes on my relatively slow home PC, and used only a steady 10MB of RAM. Here are the resulting graphs if you’re interested. 
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/rmbyers/WindowsLiveWriter/UsingLINQforComputationalGenomics_13ACC/GCDensity-Human%5B6%5D.png" mce_href="http://blogs.msdn.com/blogfiles/rmbyers/WindowsLiveWriter/UsingLINQforComputationalGenomics_13ACC/GCDensity-Human%5B6%5D.png" atomicselection="true"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=397 src="http://blogs.msdn.com/blogfiles/rmbyers/WindowsLiveWriter/UsingLINQforComputationalGenomics_13ACC/GCDensity-Human_thumb%5B4%5D.png" width=640 border=0 mce_src="http://blogs.msdn.com/blogfiles/rmbyers/WindowsLiveWriter/UsingLINQforComputationalGenomics_13ACC/GCDensity-Human_thumb%5B4%5D.png"&gt;&lt;/A&gt; 
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/rmbyers/WindowsLiveWriter/UsingLINQforComputationalGenomics_13ACC/GCDensity-Chimpanzee%5B5%5D.png" mce_href="http://blogs.msdn.com/blogfiles/rmbyers/WindowsLiveWriter/UsingLINQforComputationalGenomics_13ACC/GCDensity-Chimpanzee%5B5%5D.png" atomicselection="true"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=397 src="http://blogs.msdn.com/blogfiles/rmbyers/WindowsLiveWriter/UsingLINQforComputationalGenomics_13ACC/GCDensity-Chimpanzee_thumb%5B3%5D.png" width=640 border=0 mce_src="http://blogs.msdn.com/blogfiles/rmbyers/WindowsLiveWriter/UsingLINQforComputationalGenomics_13ACC/GCDensity-Chimpanzee_thumb%5B3%5D.png"&gt;&lt;/A&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2474445" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/rmbyers/archive/tags/Languages/default.aspx">Languages</category><category domain="http://blogs.msdn.com/rmbyers/archive/tags/Science/default.aspx">Science</category></item><item><title>More on generic variance</title><link>http://blogs.msdn.com/rmbyers/archive/2006/06/01/613690.aspx</link><pubDate>Fri, 02 Jun 2006 04:44:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:613690</guid><dc:creator>rmbyers</dc:creator><slash:comments>20</slash:comments><comments>http://blogs.msdn.com/rmbyers/comments/613690.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rmbyers/commentrss.aspx?PostID=613690</wfw:commentRss><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;In &lt;A href="/rmbyers/archive/2005/02/16/375079.aspx"&gt;my entry on generic variance in the CLR&lt;/A&gt;, I said that you can’t convert a List&amp;lt;String&amp;gt; to a List&amp;lt;Object&amp;gt;, or even an IEnumerable&amp;lt;String&amp;gt; to IEnumerable&amp;lt;Object&amp;gt;.&amp;nbsp; I should point out however that the real-world scenarios where you’d want to do this usually involve passing an object of a more specific type to an API that (for abstraction reasons) takes a less specific type.&amp;nbsp; For example, say you have a class hierarchy like this:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;abstract&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;Shape&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;abstract&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt; ComputeArea();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;Square&lt;/SPAN&gt; : &lt;SPAN style="COLOR: teal"&gt;Shape&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; Square(&lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt; height)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_height = height;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt; ComputeArea()&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; m_height * m_height;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt; m_height;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;Circle&lt;/SPAN&gt; : &lt;SPAN style="COLOR: teal"&gt;Shape&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; Circle(&lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt; radius)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_radius = radius;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;override&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt; ComputeArea()&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;Math&lt;/SPAN&gt;.PI * m_radius * m_radius;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt; m_radius;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;You’d like to be able to use it uniformly like this:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;Program&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; &lt;?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /&gt;&lt;st1:place w:st="on"&gt;Main&lt;/st1:place&gt;(&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;[] args)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: teal"&gt;List&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: teal"&gt;Square&lt;/SPAN&gt;&amp;gt; ls = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;List&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: teal"&gt;Square&lt;/SPAN&gt;&amp;gt;(); &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ls.Add(&lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;Square&lt;/SPAN&gt;(2));&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ls.Add(&lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;Square&lt;/SPAN&gt;(3));&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt; totS = GetTotalArea(ls); &lt;FONT color=#008000&gt;// won’t compile&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: teal"&gt;List&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: teal"&gt;Circle&lt;/SPAN&gt;&amp;gt; lc = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;List&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: teal"&gt;Circle&lt;/SPAN&gt;&amp;gt;();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lc.Add(&lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;Circle&lt;/SPAN&gt;(2));&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lc.Add(&lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;Circle&lt;/SPAN&gt;(3));&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt; totC = GetTotalArea(lc); &lt;FONT color=#008000&gt;// won’t compile&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt; GetTotalArea( &lt;SPAN style="COLOR: teal"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: teal"&gt;Shape&lt;/SPAN&gt;&amp;gt; l) &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt; total = 0;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;foreach&lt;/SPAN&gt; (&lt;SPAN style="COLOR: teal"&gt;Shape&lt;/SPAN&gt; s &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; l)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; total += s.ComputeArea();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; total;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;This would only work if C# supported generic variance and IEnumerable was defined as IEnumerable&amp;lt;+T&amp;gt;.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;However, there is another option in this case.&amp;nbsp; You could make GetTotalArea a generic method and rely on a base-type constraint:&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt; GetTotalArea&amp;lt;T&amp;gt;(&lt;SPAN style="COLOR: teal"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;T&amp;gt; l)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;where&lt;/SPAN&gt; T : &lt;SPAN style="COLOR: teal"&gt;Shape&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;double&lt;/SPAN&gt; total = 0;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;foreach&lt;/SPAN&gt; (&lt;SPAN style="COLOR: teal"&gt;Shape&lt;/SPAN&gt; s &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; l)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;total += s.ComputeArea();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; total;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Now the above Main method will work perfectly, you don’t even have to modify it to specify the type parameters (C#’s type inference can figure them out automatically).&amp;nbsp; So although you're not really converting an IEnumerable&amp;lt;Square&amp;gt; to an IEnumerable&amp;lt;Shape&amp;gt;, you&amp;nbsp;are able to use it that way.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;This is certainly great.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;And in practice, most .NET developers will find the support in .NET 2.0 for generics to be more than powerful enough.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;However, if you’re trying to do some serious “generic programming” &lt;A href="http://faculty.cs.tamu.edu/jarvi/papers/cmp_gp.pdf"&gt;[3]&lt;/A&gt;, or if you’re excited by programming language theory like I am, then this does still leave something to be desired.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Most notably, we can specify an upper-bound using a constraint like this (rather than require our language to support covariant type parameters), but the CLR and C# don’t have support for lower bounds (“supertype constraints”) so you can’t use this technique in place of contravariant type parameters (eg. my IComparer&amp;lt;-T&amp;gt; example).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;See section 4.4 (“Comparison with Parametric Methods”) of &lt;A href="http://citeseer.ist.psu.edu/igarashi02variancebased.html"&gt;[1]&lt;/A&gt; for more details.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Java 5 addresses these scenarios with “Wildcard types” &lt;A href="http://www.daimi.au.dk/~madst/tool/tool2004/papers/wildcards.pdf"&gt;[2]&lt;/A&gt;.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Eg. you would use a “List&amp;lt;? extends Shape&amp;gt;” in Java to implement my example above, and there is also a syntax “? super T” for lower-bounds.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;It’s&amp;nbsp;interesting to note that the authors of the paper on wildcards indicate that the main advantage of wildcard types over using normal generic methods (as I’ve done above) is that wildcard types don’t require exact type information (see section 4.4 of &lt;A href="http://www.daimi.au.dk/~madst/tool/tool2004/papers/wildcards.pdf"&gt;[2]&lt;/A&gt;).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The big difference between generics in .NET and Java is that in .NET, the CLR supports generics to the core and so we have exact type information everywhere (which is why you can get information about generic types using Reflection at run-time).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;In Java, generics are “erased” by the compiler, and so at run-time, the information about generic instantiations are lost.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Using erasure has the benefit of better compatibility with old code and a much simpler implementation, but extending the VM (like we did for the CLR) has several important benefits including avoiding boxing for instantiations at value types and therefore better performance (eg. a List&amp;lt;int&amp;gt; can be very efficient), and the ability to use exact type information at run-time.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;The big difference between wildcards and generic variance in the CLR is that wildcard types are an example of “usage-site variance” where MSIL&amp;nbsp;uses “definition-site variance” (meaning it’s the type definition that specifies the variance annotation, not the user of the type).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I was reading about a cool academic programming language called &lt;A href="http://scala.epfl.ch/index.html"&gt;Scala&lt;/A&gt; recently, and was pleased to see that after some experience with usage-site variance, they decided to switch to definition-site variance because they found it easier to use correctly (see “Comparison with wildcards” in &lt;A href="http://scala.epfl.ch/docu/files/ScalaOverview.pdf"&gt;[4]&lt;/A&gt;).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Scala is a very cool language (my programming languages professor recently mentioned it as a great example of a language on the forefront of modern academic language design), and&amp;nbsp;can target .NET.&amp;nbsp; Unfortunately they haven’t built support for the V2.0 CLR yet so they aren’t actually making use of the definition-site variance support in the CLR (for the moment &amp;lt;grin&amp;gt;).&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Anyway, I think that’s about all I have to say about generic variance.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I’ve got a &lt;A href="http://www.cs.washington.edu/education/courses/csep505/06sp/"&gt;programming languages&lt;/A&gt; exam on Tuesday (I’m working on my masters in computer science) so I think I better stop procrastinating and study for it &amp;lt;grin&amp;gt;.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;References&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;[1] &lt;A href="http://pag.csail.mit.edu/reading-group/variance-ECOOP02.pdf"&gt;On variance-based subtyping for parametric types&lt;/A&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;[2] &lt;A href="http://www.daimi.au.dk/~madst/tool/tool2004/papers/wildcards.pdf"&gt;Adding Wildcards to the Java Programming Language&lt;/A&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;[3] &lt;A href="http://faculty.cs.tamu.edu/jarvi/papers/cmp_gp.pdf"&gt;A Comparative Study of Language Support for Generic Programming&lt;/A&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;[4] &lt;A href="http://scala.epfl.ch/docu/files/ScalaOverview.pdf"&gt;An Overview of the Scala Programming Language (2. Edition)&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=613690" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/rmbyers/archive/tags/Languages/default.aspx">Languages</category><category domain="http://blogs.msdn.com/rmbyers/archive/tags/CLR/default.aspx">CLR</category></item><item><title>Linq and the cost of additional language complexity</title><link>http://blogs.msdn.com/rmbyers/archive/2005/09/25/linq-and-the-cost-of-additional-language-complexity.aspx</link><pubDate>Sun, 25 Sep 2005 23:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:473767</guid><dc:creator>rmbyers</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/rmbyers/comments/473767.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rmbyers/commentrss.aspx?PostID=473767</wfw:commentRss><description>&lt;P&gt;&lt;A href="http://www.magerquark.com/"&gt;Uwe Keim&lt;/A&gt; posted a thought provoking&amp;nbsp;&lt;A href="http://blogs.msdn.com/rmbyers/archive/2005/09/24/473684.aspx#473688"&gt;comment&lt;/A&gt; in response to &lt;A href="http://blogs.msdn.com/rmbyers/archive/2005/09/24/473684.aspx"&gt;my entry about Linq&lt;/A&gt;.&amp;nbsp; Here is an excerpt:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;I do see the benefits, but I also have a big déjà vû: The C#-language seems to go the C++-way, where I, even after 10 years of programming, don't know all of the features and sometimes still wonder "why does this thing behave this way?".&amp;nbsp; So the complexity is raised from version to version. Does everyone think, this is a good way? I think it would be better to NOT enhance the language/compiler from version to version, but to enhance functionality by enhancing the library instead. &lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;I think the added complexity concern is a valid one which deserves careful analysis.&amp;nbsp; I'll&amp;nbsp;just touch on my thoughts here.&lt;/P&gt;
&lt;P dir=ltr&gt;One important difference between C++ and C#/VB is that C++ is designed by committee, where C# and VB each have a chief architect (Anders Hejlsberg and Paul Vick respectively) who doesn't have to try and satisfy everyone's favorite language request.&amp;nbsp; I know the complexity concern is something Anders and his team have taken very seriously (as have the VB folks).&amp;nbsp; I've heard Anders talk about the fact that they have to be extremely careful about this, and that he'd rather err on the side of caution.&amp;nbsp; The C# team has rejected several of my favorite language features (such as generic variance, C++ style const, etc.) because they felt the benefits for the average user didn't significantly outweigh the extra complexity (even through there were compelling benefits for SOME users).&amp;nbsp; This is where a lot of the "art" of language design comes into play.&amp;nbsp; Personally I have a lot of respect for Anders and Paul and trust their judgment and the customer research their teams have done which concluded that in this case the extra complexity was justified.&amp;nbsp; As much as I'd like to believe otherwise, there is probably a good reason here why Anders is the chief C# architect and you and I are not &amp;lt;grin&amp;gt;.&lt;/P&gt;
&lt;P&gt;Of course they could be wrong,&amp;nbsp;and it's important that Microsoft and our customers evaluate this risk seriously.&amp;nbsp; Uwe suggested a compiler plug-in model where you could enable different features on demand.&amp;nbsp; I'd love a public compiler plug-in model - there are so many cool features I'd like to add and use in my code.&amp;nbsp; I've even asked Anders about this (in the context of the fact that expression trees means that some errors that could normally be detected a compile time now become run-time errors), and he indicated that to maintain simplicity and comprehensibility they are avoiding any such dynamic / customizable compiler behavior.&amp;nbsp; I think Anders has a point here.&amp;nbsp; In this case, just using the v1.1 or v2.0 compiler to target the latest CLR has similar benefits except that the possible feature combinations are fixed to well known sets, which avoids the confusion and complexity of the plug-in or optional feature model.&lt;/P&gt;
&lt;P&gt;The other thing to keep in mind is that a lot of effort went into reducing complexity by adding a few powerful general language concepts, instead of many feature-specific concepts.&amp;nbsp; I think Linq did even better than Cω in this respect.&amp;nbsp; For example, unlike the Cω compiler, the C# 3.0 compiler has no knowledge of databases, SQL or XML, it's all in the DLinq and XLinq&amp;nbsp;libraries.&amp;nbsp; Personally, I find the new language features in the C# 3.0 spec to be quite simple and elegant, but then I'm a (functional) programming languages nerd so I'm not exactly the target audience.&lt;/P&gt;
&lt;P&gt;Ultimately it will be up to our customers.&amp;nbsp; If, after seriously experimenting and evaluating Linq,&amp;nbsp;you think the extra complexity isn't worth the benefit, then it's important that you give us your feedback&amp;nbsp;(we're getting better and better at &lt;A href="http://lab.msdn.microsoft.com/ProductFeedback/Default.aspx"&gt;listening&lt;/A&gt; to this sort of thing).&amp;nbsp; On the other hand, the response from the PDC was overwhelmingly positive, so it would be likely to be an uphill battle &amp;lt;grin&amp;gt;.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=473767" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/rmbyers/archive/tags/Languages/default.aspx">Languages</category><category domain="http://blogs.msdn.com/rmbyers/archive/tags/Software+engineering/default.aspx">Software engineering</category></item><item><title>Comparison of a simple select statement in DLinq (C# 3.0) vs. ADO.Net</title><link>http://blogs.msdn.com/rmbyers/archive/2005/09/24/comparison-of-a-simple-select-statement-in-dlinq-c-3-0-vs-ado-net.aspx</link><pubDate>Sun, 25 Sep 2005 07:59:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:473684</guid><dc:creator>rmbyers</dc:creator><slash:comments>11</slash:comments><comments>http://blogs.msdn.com/rmbyers/comments/473684.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rmbyers/commentrss.aspx?PostID=473684</wfw:commentRss><description>&lt;P&gt;Six months ago I posted a &lt;a href="http://blogs.msdn.com/rmbyers/archive/2005/03/20/399489.aspx"&gt;comparison of a simple select statement in C-omega vs. ADO.Net&lt;/A&gt;&amp;nbsp;which some people &lt;a href="http://blogs.msdn.com/rmbyers/archive/2005/03/20/399489.aspx#comments"&gt;found&lt;/A&gt; very exciting.&amp;nbsp; Now that &lt;A href="http://msdn.microsoft.com/netframework/future/linq/default.aspx"&gt;Linq&lt;/A&gt; has been officially unveiled, I figured I should update my comparison using &lt;A href="http://download.microsoft.com/download/9/5/0/9503e33e-fde6-4aed-b5d0-ffe749822f1b/csharp%203.0%20specification.doc"&gt;C# 3.0&lt;/A&gt; and &lt;A href="http://download.microsoft.com/download/c/f/b/cfbbc093-f3b3-4fdb-a170-604db2e29e99/DLinq%20Overview.doc"&gt;DLinq&lt;/A&gt;.&amp;nbsp; Although Linq and C-omega have some significant differences, everything I said in that post about the benefits of C-omega applies equally well to Linq (in fact, I like Linq even better, primarily due to &lt;A href="http://msdn.microsoft.com/netframework/future/linq/default.aspx?pull=/library/en-us/dndotnet/html/linqprojectovw.asp"&gt;expression trees&lt;/A&gt;) [Update: &lt;A href="http://research.microsoft.com/~emeijer/"&gt;Erik Meijer&lt;/A&gt;&amp;nbsp;e-mailed me to say that C-omega also has indirect support&amp;nbsp;for expression trees by&amp;nbsp;exposing the parse tree to compiler plug-ins.]&lt;/P&gt;
&lt;P&gt;Here is the example ADO.Net code using strongly-typed data sets:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SqlDataAdapter da = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; SqlDataAdapter(&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;"SELECT * FROM &lt;?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /&gt;&lt;st1:place w:st="on"&gt;&lt;st1:PlaceName w:st="on"&gt;Employees&lt;/st1:PlaceName&gt; &lt;st1:PlaceName w:st="on"&gt;WHERE&lt;/st1:PlaceName&gt; &lt;st1:PlaceType w:st="on"&gt;City&lt;/st1:PlaceType&gt;&lt;/st1:place&gt;= @city", nwindConn );&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SqlParameter cityParam = da.SelectCommand.Parameters.Add("@city", SqlDbType.VarChar, 80);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;cityParam.Value = city;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;NorthwindDataSet ds = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; NorthwindDataSet();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;da.Fill(ds, ds.Employees.TableName );&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;foreach&lt;/SPAN&gt; (NorthwindDataSet.EmployeesRow dr &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; ds.Employees.Rows)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; name = dr.LastName;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt; id = dr.EmployeeID;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Console.WriteLine( id + ": " + name);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;And here is the equivalent C# 3.0 code:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&lt;FONT color=#0000ff&gt;var&lt;/FONT&gt; rows =&amp;nbsp;&lt;FONT color=#0000ff&gt;from&lt;/FONT&gt; e &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; db.Employees&amp;nbsp;&lt;FONT color=#0000ff&gt;where&lt;/FONT&gt; e.City == city&amp;nbsp;&lt;FONT color=#0000ff&gt;select&lt;/FONT&gt; e;&lt;BR&gt;&lt;FONT color=#0000ff&gt;foreach&lt;/FONT&gt;( &lt;FONT color=#0000ff&gt;var&lt;/FONT&gt; e &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; rows )&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;FONT color=#0000ff&gt;string&lt;/FONT&gt; name = e.LastName;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;FONT color=#0000ff&gt;int&lt;/FONT&gt; id = e.EmployeeID;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine( id + ": " + name );&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;Or even more concisely:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P dir=ltr&gt;&lt;FONT face="Courier New" size=2&gt;&lt;FONT color=#0000ff&gt;foreach&lt;/FONT&gt;( &lt;FONT color=#0000ff&gt;var&lt;/FONT&gt; e &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; db.Employees.Where( e =&amp;gt; e.City == city ) )&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine( e.EmployeeID + ": " + e.LastName );&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr&gt;There is already &lt;A href="http://msdn.microsoft.com/netframework/future/linq/default.aspx"&gt;tons of information&lt;/A&gt; available about Linq (more so than there ever was for C-omega), and there are some great blogs by plenty of people more authoritative than myself (eg &lt;a href="http://blogs.msdn.com/mattwar/"&gt;Matt&lt;/A&gt;, &lt;a href="http://blogs.msdn.com/Dinesh.Kulkarni"&gt;Dinesh&lt;/A&gt;, &lt;A href="http://www.panopticoncentral.net/"&gt;Paul&lt;/A&gt;, &lt;a href="http://blogs.msdn.com/danielfe/"&gt;Dan&lt;/A&gt;, &lt;a href="http://blogs.msdn.com/scottwil/"&gt;Scott&lt;/A&gt;, etc.), so I probably won't say much more about it myself.&amp;nbsp; But isn't it awesome that this is almost certainly going to become part of mainstream programming in a couple years?&amp;nbsp; Are we finally on the road to eliminating SQL injection attacks (not to mention all the other great benefits)?&amp;nbsp; It's advances like this that make me proud to work for Microsoft!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=473684" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/rmbyers/archive/tags/Languages/default.aspx">Languages</category></item><item><title>Interested in C-omega?  LINQ finally announced!</title><link>http://blogs.msdn.com/rmbyers/archive/2005/09/13/interested-in-c-omega-linq-finally-announced.aspx</link><pubDate>Wed, 14 Sep 2005 01:07:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:465161</guid><dc:creator>rmbyers</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/rmbyers/comments/465161.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rmbyers/commentrss.aspx?PostID=465161</wfw:commentRss><description>&lt;P&gt;Ever since I started planning for my &lt;a href="http://blogs.msdn.com/rmbyers/archive/2005/04/04/405414.aspx"&gt;users-group talk&lt;/A&gt; (and wrote &lt;a href="http://blogs.msdn.com/rmbyers/archive/2005/03/20/399489.aspx"&gt;this blog entry&lt;/A&gt;) about data access with C-omega, I've been dying to tell everyone about the plans to add similar functionality to C#.&amp;nbsp; For those of you at my talk, you'll remember this &lt;A href="http://www.theserverside.net/talks/videos/AndersHejlsberg/interview.tss?bandwidth=dsl"&gt;video of Anders&lt;/A&gt; which alluded to the work that was being done here.&amp;nbsp; Well, today at the PDC, &lt;A href="http://msdn.microsoft.com/netframework/future/linq/"&gt;project LINQ&lt;/A&gt;&amp;nbsp;(formerly "Clarity", etc.) was publicly announced.&amp;nbsp; In a nutshell, C# 3.0 (and VB 9.0)&amp;nbsp;will add fundamental support for seamlessly working with data, which includes several core language enhancements that are generally useful (such as type inference).&amp;nbsp; Functional programming language fans (such as myself) should find the design especially appealing.&amp;nbsp; See the &lt;A href="http://msdn.microsoft.com/netframework/future/linq/"&gt;LINQ website&lt;/A&gt; for details.&lt;/P&gt;
&lt;P&gt;This is definitely the one thing I'm most excited about in the Orcas (3.0) release.&amp;nbsp; Not only is it cool for programming-language theory fans, but it also has the potential to significantly improve the productivity of a typical enterprise developer.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=465161" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/rmbyers/archive/tags/Languages/default.aspx">Languages</category></item><item><title>Comega talk</title><link>http://blogs.msdn.com/rmbyers/archive/2005/04/04/405414.aspx</link><pubDate>Tue, 05 Apr 2005 06:48:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:405414</guid><dc:creator>rmbyers</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/rmbyers/comments/405414.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rmbyers/commentrss.aspx?PostID=405414</wfw:commentRss><description>&lt;P&gt;On Thursday I gave a &lt;A href="http://www.cttdnug.org/DesktopDefault.aspx?tabid=71"&gt;.NET users group talk&lt;/A&gt; on &lt;A href="http://research.microsoft.com/Comega/"&gt;Comega&lt;/A&gt;&amp;nbsp;to somewhere around 100 .NET developers.&amp;nbsp; Overall I think it went pretty well.&amp;nbsp; I was nervous at first, but once I got into talking about the cool stuff I like I forgot about the pressure and had a good time.&amp;nbsp; If you were there, please let me know what you thought about both my presentation style and the technical content.&lt;/P&gt;
&lt;P&gt;I asked the audience how many of them wrote a lot of code for interacting with databases or XML data, and almost every hand went up.&amp;nbsp; My premise was that there was a huge potential to improve the productivity, quality and security&amp;nbsp;of a lot of mainstream software development through data-oriented language features like those in Comega, and that if customers&amp;nbsp;agreed, it was their responsibility to demand these features from the industry.&amp;nbsp; In my opinion, we're far too content as programmers to go about doing things the way we've always done them&amp;nbsp;rather than push for (and pay for) better ways of building systems (obviously finding the right balance here is hard).&amp;nbsp; Perhaps this reflects a typically short-term-oriented reward system of the software industry (shipping the next new feature sooner), or perhaps it just reflects a cynicism of a market full of&amp;nbsp;half-baked "improve productivity quickly" products that lack empirical data and research (which development shops often aren't eager to share).&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;One thing that surprised me was that when I showed the &lt;a href="http://blogs.msdn.com/rmbyers/archive/2005/03/20/399489.aspx"&gt;naive ADO.Net&amp;nbsp;query code&lt;/A&gt; and asked the audience what the problems were with it, it wasn't until the 3rd&amp;nbsp;response a minute or so into the discussion that someone said it was vulnerable to a SQL injection attack.&amp;nbsp; This may have just been typical developer shyness to&amp;nbsp;answer obvious questions, but I had expected that to be the most obvious response.&amp;nbsp; Regardless, it is scary how easy it is to fall into this trap without noticing right away that constructing a SQL query based on user input is a bad idea.&amp;nbsp; It's also unfortunate how many more keys you need to press (~128 in &lt;a href="http://blogs.msdn.com/rmbyers/archive/2005/03/20/399489.aspx"&gt;my example&lt;/A&gt;) to avoid the problem.&lt;/P&gt;
&lt;P&gt;There was some great discussion around how Comega might or might not be able to also help with the encapsulation typically provided by business objects.&amp;nbsp; After playing with some options and thinking about this a bit more, I think the two issues (accessing back-end data, and exposing that data through business objects) are largely orthogonal.&amp;nbsp; If you want to add a layer of abstraction that provides encapsulation, data hiding, client-side validation, etc. then you're still going to have to wrap the data in some custom objects that define the interface and logic you want.&amp;nbsp; However, Comega can make it much easier to implement those objects, especially due to the simple syntax for converting data to different shapes.&lt;/P&gt;
&lt;P&gt;Anyway, for those of you that asked me after the presentation to post my slide deck, &lt;A href="http://www.iaw.com/rickb/files/CTTDNUG%20Comega.ppt"&gt;here it is&lt;/A&gt;.&amp;nbsp; Sorry I didn't post sooner, but my whirlwind vacation in Ontario was pretty hectic.&amp;nbsp; Here also are some links to papers and relevant video:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://research.microsoft.com/users/schulte/Papers/UnifyingTablesObjectsAndDocuments(DPCOOL2003).pdf"&gt;Unifying Tables, Objects and Documents&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://research.microsoft.com/~gmb/Papers/vanilla-xml2003.html"&gt;Programming with Rectangles, Triangles, and Circles&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://research.microsoft.com/%7Eemeijer/Papers/popl.pdf"&gt;The essence of data access in Cω&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://channel9.msdn.com/ShowPost.aspx?PostID=23947"&gt;Gavin Bierman (MSR)&amp;nbsp;on Comega&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://www.theserverside.net/talks/videos/AndersHejlsberg/interview.tss?bandwidth=dsl"&gt;Anders Hejlsberg on the future of C# and other things&lt;/A&gt;&amp;nbsp;(it was question #17&amp;nbsp;that I played during the talk) 
&lt;LI&gt;&lt;A href="http://channel9.msdn.com/ShowPost.aspx?PostID=10991"&gt;Anders Hejlsberg - Programming data in C# 3.0&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=405414" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/rmbyers/archive/tags/Languages/default.aspx">Languages</category></item><item><title>Comparison of a simple select statement in C-omega vs. ADO.Net</title><link>http://blogs.msdn.com/rmbyers/archive/2005/03/20/399489.aspx</link><pubDate>Mon, 21 Mar 2005 04:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:399489</guid><dc:creator>rmbyers</dc:creator><slash:comments>20</slash:comments><comments>http://blogs.msdn.com/rmbyers/comments/399489.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rmbyers/commentrss.aspx?PostID=399489</wfw:commentRss><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;In a couple weeks, I'm doing a &lt;A href="http://www.cttdnug.org/DesktopDefault.aspx?tabid=71"&gt;talk at a .NET users group in Ontario&lt;/A&gt; about &lt;A href="http://research.microsoft.com/comega/"&gt;Cω&lt;/A&gt;. Cω&amp;nbsp;is a&amp;nbsp;cool research language from Microsoft Research that extends C# with direct support for data access (SQL and XML) and concurrency abstractions.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I’ve been planning on writing a number of blog entries about Cω, but I haven’t yet been able to make the time.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;I was just working on the slides for my talk and thought I’d at least post one of my examples comparing simple database access with ADO.Net and Cω.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;One important concept in efficiently building reliable and maintainable software is “discover errors as early (and cheaply) as possible”.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;With that in mind, let’s look at some code (disclaimer: I’m by no means an ADO.Net expert).&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Say we just want to get the names of all the employees who live in a specific city (in the sample Northwind database that comes with SQL Server).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;The simplest approach has a number of well-known problems:&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SqlDataAdapter da = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; SqlDataAdapter(&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;"SELECT * FROM &lt;?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /&gt;&lt;st1:place w:st="on"&gt;&lt;st1:PlaceName w:st="on"&gt;Employees&lt;/st1:PlaceName&gt; &lt;st1:PlaceName w:st="on"&gt;WHERE&lt;/st1:PlaceName&gt; &lt;st1:PlaceType w:st="on"&gt;City&lt;/st1:PlaceType&gt;&lt;/st1:place&gt;='"+city+"'", nwindConn );&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; TEXT-INDENT: 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;DataSet ds = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; DataSet();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;da.Fill(ds,"Employees");&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;foreach&lt;/SPAN&gt; (DataRow dr &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; ds.Tables["Employees"].Rows)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; name = dr["LastName"].ToString();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;int&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt; id = (&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;)dr["EmployeeID"];&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Console.WriteLine( id + ": " + name);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;DIV class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;/o:p&gt;The argument ‘city’ is subject to a SQL injection attack&lt;/DIV&gt;
&lt;LI&gt;
&lt;DIV class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;The data is weakly typed, so we have to cast to get what we want, which could fail at run-time&lt;/DIV&gt;
&lt;LI&gt;
&lt;DIV class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Several string literals (table and column names) are used which could result in run-time errors&lt;/DIV&gt;
&lt;LI&gt;
&lt;DIV class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;The query is stored as a string providing no opportunity for validation before run-time&lt;o:p&gt;&lt;/o:p&gt;&lt;/DIV&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;We prevent the injection attack by using SqlParameters, and use strongly typed data sets to prevent the problems with string literals and casting:&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SqlDataAdapter da = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; SqlDataAdapter(&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;"SELECT * FROM &lt;st1:place w:st="on"&gt;&lt;st1:PlaceName w:st="on"&gt;Employees&lt;/st1:PlaceName&gt; &lt;st1:PlaceName w:st="on"&gt;WHERE&lt;/st1:PlaceName&gt; &lt;st1:PlaceType w:st="on"&gt;City&lt;/st1:PlaceType&gt;&lt;/st1:place&gt;= @city", nwindConn );&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SqlParameter cityParam = da.SelectCommand.Parameters.Add("@city", SqlDbType.VarChar, 80);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;cityParam.Value = city;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;NorthwindDataSet ds = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; NorthwindDataSet();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;da.Fill(ds, ds.Employees.TableName );&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;foreach&lt;/SPAN&gt; (NorthwindDataSet.EmployeesRow dr &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; ds.Employees.Rows)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; name = dr.LastName;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt; id = dr.EmployeeID;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Console.WriteLine( id + ": " + name);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;This is a lot better (although people are often too lazy to write the extra code to use SqlParameters).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;However, the SQL command is still stored as a string meaning we won’t find any errors in it until run-time, and the relationship between the shape of its output and the NorthwindDataSet is implicit and brittle.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;We might want to put the SQL into a stored procedure:&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;CREATE PROCEDURE &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;EmployeesForCity&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;@City &lt;SPAN style="COLOR: blue"&gt;nvarchar&lt;/SPAN&gt;(80)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;AS&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;SELECT EmployeeID, LastName&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt; &lt;SPAN style="COLOR: blue"&gt;FROM &lt;/SPAN&gt;&lt;st1:place w:st="on"&gt;&lt;st1:PlaceName w:st="on"&gt;Employees&lt;/st1:PlaceName&gt; &lt;st1:PlaceName w:st="on"&gt;&lt;SPAN style="COLOR: blue"&gt;WHERE&lt;/SPAN&gt;&lt;/st1:PlaceName&gt;&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;st1:PlaceType w:st="on"&gt;City&lt;/st1:PlaceType&gt;&lt;/st1:place&gt; = @City&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;And then write our code without explicit knowledge of the structure of the underlying database:&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SqlCommand cmd = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; SqlCommand( "dbo.EmployeesForCity", nwindConn );&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;cmd.CommandType = CommandType.StoredProcedure;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SqlParameter cityParam = cmd.Parameters.Add("@city", SqlDbType.VarChar, 80);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;cityParam.Value = city;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;SqlDataAdapter da = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; SqlDataAdapter( cmd );&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;NorthwindDataSet ds = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; NorthwindDataSet();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;da.Fill(ds, ds.EmployeesForCity.TableName );&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;foreach&lt;/SPAN&gt; (NorthwindDataSet.EmployeesForCityRow dr &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; ds.EmployeesForCity.Rows)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; name = dr.LastName;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt; id = dr.EmployeeID;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Console.WriteLine( id + ": " + name);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;This is better; at least now our SQL statement can be checked before we run our app.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;However, we still have some literal strings in our code, and we’re still going to get a run-time error if the stored procedure changes in some way (I don’t see any easy way to rebuild the XSD from the database schema in VS.Net 2003).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Plus, we’ve had to write significantly more code here.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;At best, it feels like our code has a weak connection to the underlying database.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;For small programs like this, it’s no big deal.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;But for large data-intensive programs, people complain a lot about spending a lot of the time messing with plumbing code.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Here’s the equivalent code in Cω:&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;rows = &lt;SPAN style="COLOR: blue"&gt;select&lt;/SPAN&gt; * &lt;SPAN style="COLOR: blue"&gt;from&lt;/SPAN&gt; DB.Employees &lt;SPAN style="COLOR: blue"&gt;where&lt;/SPAN&gt; City == city; &lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;foreach&lt;/SPAN&gt;( row &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; rows ) &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; name = row.LastName.Value;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt; id = row.EmployeeID.Value;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Console.WriteLine( id.ToString() + ": " + name);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;Note the following:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;DIV class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;There is no knowledge embedded in string literals&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;LI&gt;
&lt;DIV class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;The select statement is strongly typed, meaning that we know exactly at compile-time what the shape of the data will look like (intellisense even shows us), and what valid statements are.&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;LI&gt;
&lt;DIV class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;We can embed local variables like “city” directly into our sql without worrying about injection attacks.&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;LI&gt;
&lt;DIV class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;We can rely on type inference so we don’t have to explicitly specify the type of “rows” and “row”, even though it is strongly typed.&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;LI&gt;
&lt;DIV class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;We can configure our build such that we’ll know at compile time if the database has changed in any way that would make the code fail.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Of course the database could still be changed underneath our program resulting in a run-time error if we don’t recompile.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;And if you are willing to abandon SQL syntax all together, you could equivalently write:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;DB.Employees [City==city].{ &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Console.WriteLine( &lt;SPAN style="COLOR: blue"&gt;it&lt;/SPAN&gt;.EmployeeID + ": " + &lt;SPAN style="COLOR: blue"&gt;it&lt;/SPAN&gt;.LastName ); &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;};&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;How do you like that for concisely expressing what you mean?&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"&gt;&lt;o:p&gt;[Update: Added &lt;a href="http://blogs.msdn.com/rmbyers/archive/2005/09/24/473684.aspx"&gt;entry&lt;/A&gt; with C# 3.0 / DLinq syntax for this comparison]&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=399489" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/rmbyers/archive/tags/Languages/default.aspx">Languages</category></item><item><title>Generic type parameter variance in the CLR</title><link>http://blogs.msdn.com/rmbyers/archive/2005/02/16/generic-type-parameter-variance-in-the-clr.aspx</link><pubDate>Thu, 17 Feb 2005 10:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:375079</guid><dc:creator>rmbyers</dc:creator><slash:comments>19</slash:comments><comments>http://blogs.msdn.com/rmbyers/comments/375079.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rmbyers/commentrss.aspx?PostID=375079</wfw:commentRss><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;When people start using C# generics for the first time, they are sometimes surprised that they can’t convert between related generic instances.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;For example, since you can convert a &lt;/SPAN&gt;&lt;SPAN style="mso-no-proof: yes"&gt;string&lt;/SPAN&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt; to an &lt;/SPAN&gt;&lt;SPAN style="mso-no-proof: yes"&gt;object&lt;/SPAN&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;, shouldn’t you also be able to convert a &lt;/SPAN&gt;&lt;SPAN style="mso-no-proof: yes; mso-bidi-font-weight: bold"&gt;List&lt;/SPAN&gt;&lt;SPAN style="mso-no-proof: yes"&gt;&amp;lt;string&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: EN-CA"&gt; &lt;SPAN lang=EN&gt;to a &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="mso-no-proof: yes; mso-bidi-font-weight: bold"&gt;List&lt;/SPAN&gt;&lt;SPAN style="mso-no-proof: yes"&gt;&amp;lt;object&amp;gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;?&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;After all, you can convert a &lt;/SPAN&gt;&lt;SPAN style="mso-no-proof: yes"&gt;string[]&lt;/SPAN&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt; to an &lt;/SPAN&gt;&lt;SPAN style="mso-no-proof: yes"&gt;object[]&lt;/SPAN&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;, why should List&amp;lt;T&amp;gt; be any different?&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;More formally, in C# v2.0 if T is a subtype of U, then T[] is a subtype of U[], but G&amp;lt;T&amp;gt; is not a subtype of G&amp;lt;U&amp;gt; (where G is any generic type).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;In type-theory terminology, we describe this &lt;/SPAN&gt;behavior&lt;SPAN style="mso-ansi-language: EN-CA"&gt; &lt;SPAN lang=EN&gt;by saying that C# array types are “covariant” and generic types are “invariant”.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;There is actually a reason why you might consider generic type invariance to be a good thing.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Consider the following code:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; TEXT-INDENT: 0.5in; mso-layout-grid-align: none"&gt;&lt;B&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: navy; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;List&lt;/SPAN&gt;&lt;/B&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&amp;lt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;&amp;gt; ls = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;B&gt;&lt;SPAN style="COLOR: navy"&gt;List&lt;/SPAN&gt;&lt;/B&gt;&amp;lt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;&amp;gt;();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ls.Add("test");&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;B&gt;&lt;SPAN style="COLOR: navy"&gt;List&lt;/SPAN&gt;&lt;/B&gt;&amp;lt;&lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt;&amp;gt; lo = ls;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// Can't do this in C#&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt; o1 = lo[0];&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// ok – converting string to object&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;lo[0] = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt;();&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// ERROR – can’t convert object to string&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;If this were allowed, the last line would have to result in a run-time type-check (to preserve type safety), which could throw an exception (eg. InvalidCastException).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This wouldn’t be the end of the world, but it would be unfortunate.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Part of the benefit of generic types is that it helps to avoid the run-time checking and error handling overhead involved in converting back and forth from a base type (object in C#).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;It simplifies things greatly (both from a developer and run-time perspective) to be able to say that a variable of type List&amp;lt;object&amp;gt; can for sure hold any object.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;So what about arrays, don’t we have the exact problem there?&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Yep.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;This was a hotly debated aspect to C#/CLR design.&amp;nbsp; Java also has covariant array types, and whether or not this is a language flaw has been &lt;A href="http://c2.com/cgi/wiki?JavaArraysBreakTypeSafety" mce_href="http://c2.com/cgi/wiki?JavaArraysBreakTypeSafety"&gt;debated&lt;/A&gt; for ages. Jim Miller has an interesting annotation in his &lt;A href="http://www.amazon.com/exec/obidos/tg/detail/-/0321154932" mce_href="http://www.amazon.com/exec/obidos/tg/detail/-/0321154932"&gt;CLI book&lt;/A&gt; (pg&amp;nbsp;59) where he says "The decision to support covariant arrays was primarily to allow Java to run on the VES.&amp;nbsp; The&amp;nbsp;covariant design is not thought to be the best design in&amp;nbsp;general, but it was chosen in the interest of broad reach".&amp;nbsp;&amp;nbsp;[Update: I've heard that Bill Joy, one of the original Java designers, has since said that he tried to remove array covariance in 1995 but wasn't able to do it in time, and has regretted having it in Java ever since]&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;Let’s get back to our original question.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;What if you really did want covariant generic types in a .NET language?&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Does the CLR really prevent that?&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Well, you may recall that I &lt;A href="http://blogs.msdn.com/rmbyers/archive/2005/02/08/369646.aspx" mce_href="http://blogs.msdn.com/rmbyers/archive/2005/02/08/369646.aspx"&gt;alluded&lt;/A&gt; to the fact that Eiffel makes use of additional features in the CLR generic support, that C# and VB do not.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;In Eiffel, generic types are always covariant (and so have the same sort of run-time checks as arrays).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;If you were to look at the &lt;A href="http://msdn.microsoft.com/net/ECMA/#Working Draft 2.9.1"&gt;draft v2 ECMA specification&lt;/A&gt;, you would see the following:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=Text style="MARGIN: 0in 0in 0pt 25pt"&gt;&lt;FONT size=2&gt;In addition, CLI supports covariant&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;and contravariant&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;generic parameters, with the following characteristics:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 61pt; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo2; tab-stops: list 61.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"&gt;&lt;SPAN style="mso-list: Ignore"&gt;·&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;It is type-safe (based on purely static checking) &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 61pt; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo2; tab-stops: list 61.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"&gt;&lt;SPAN style="mso-list: Ignore"&gt;·&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;Simplicity: in particular, variance is only permitted on generic interfaces and generic delegates (not classes or value-types) &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 61pt; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo2; tab-stops: list 61.0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"&gt;&lt;SPAN style="mso-list: Ignore"&gt;·&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;Languages not wishing to support variance can ignore the feature, and treat all generic types as non-variant. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 61pt; TEXT-INDENT: -0.25in; mso-list: l0 level1 lfo2; tab-stops: list 61.0pt"&gt;&lt;SPAN style="FONT-FAMILY: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol"&gt;&lt;SPAN style="mso-list: Ignore"&gt;·&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt"&gt;Enable implementation of more complex covariance scheme as used in some languages, e.g. Eiffel.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;Contravariance is the opposite of covariance – it means that the subtype relationship of the generic type varies inversely with the relationship of the type parameter.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Or formally, G&amp;lt;T&amp;gt; is a subtype of G&amp;lt;U&amp;gt; if and only if U is a subtype of T. &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;This is a pretty cool approach in my opinion.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;It allows a compiler to mark generic type parameters on an interface as being nonvariant, covariant or contravariant, and then enforces that those types are used only in places where they are safe (i.e. don’t require a run-time type check).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Specifically, it’s always safe to use a covariant type as an output (return type or out parameter), and a contravariant type as an input.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;In IL, covariant type parameters are indicated by a ‘+’, and contravariant type parameters are indicated by a ‘-‘ (non-variant type parameters are the default, and can be used anywhere).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Consider this simple example (using a theoretical extension of C#) from the draft ECMA spec [Update: switched to the newly announced C# 4.0 syntax]:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;// Covariant parameters can be used as result types&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;interface&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; &lt;SPAN style="COLOR: teal"&gt;IEnumerator&lt;/SPAN&gt;&amp;lt;&lt;FONT color=#0000ff&gt;out&lt;/FONT&gt; T&amp;gt; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;T Current { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;bool&lt;/SPAN&gt; MoveNext();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;// Covariant parameters can be used in covariant result types&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;interface&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; &lt;SPAN style="COLOR: teal"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;FONT color=#0000ff&gt;out &lt;/FONT&gt;T&amp;gt; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: teal"&gt;IEnumerator&lt;/SPAN&gt;&amp;lt;T&amp;gt; GetEnumerator();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;// Contravariant parameters can be used as argument types&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;interface&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; &lt;SPAN style="COLOR: teal"&gt;IComparer&lt;/SPAN&gt;&amp;lt;&lt;FONT color=#0000ff&gt;in &lt;/FONT&gt;T&amp;gt; { &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;bool&lt;/SPAN&gt; Compare(T x, T y);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;}&lt;/SPAN&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;This would mean we could write code like the following:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: teal"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;&amp;gt; stringCollection = ...;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: teal"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt;&amp;gt; objectCollection = stringCollection;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;foreach&lt;/SPAN&gt;( &lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt; o &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; objectCollection ) { ... }&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: teal"&gt;IComparer&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt;&amp;gt; objectComparer = ...;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: teal"&gt;IComparer&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;&amp;gt; stringComparer = objectComparer;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;bool&lt;/SPAN&gt; b = stringComparer.Compare( "x", "y" );&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;But we couldn’t do the opposite – try and convert an IEnumerable&amp;lt;object&amp;gt; to an IEnumerable&amp;lt;string&amp;gt;, or try and convert an IComparer&amp;lt;string&amp;gt; to an IComparer&amp;lt;object&amp;gt;.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;In those cases, we’d get a compile time error telling us such a conversion wouldn’t be type-safe.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Of course, languages (like Eiffel) are free to build their own run-time type checking on top of the strict CLR support to relax the rules where they see fit.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;In my opinion this sort of language feature would occasionally be very useful (although the real scenarios would, of course, be much more involved than the above simplistic examples).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;There have been a couple of times when writing real-world C# code when I knew I could write simpler code if the CLR generic variance support was exposed in C#.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Generic variance support in C# has been &lt;A href="http://lab.msdn.microsoft.com/productfeedback/ViewFeedback.aspx?FeedbackID=ea80309b-bb88-4bd3-af35-07dae204287b" mce_href="http://lab.msdn.microsoft.com/productfeedback/ViewFeedback.aspx?FeedbackID=ea80309b-bb88-4bd3-af35-07dae204287b"&gt;discussed&lt;/A&gt; on the MSDN product feedback center, and I don’t think the C# team has ruled it out for a future addition to the language (but of course I don’t know their plans any better than you do).&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Although I think this is a cool feature, I don’t think I’m going to start writing any applications in IL just so I can take advantage of it.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;However, it would probably be a fun project to write or extend and existing free C# compiler (like Mike Stall’s &lt;A href="http://blogs.msdn.com/jmstall/archive/2005/02/06/368192.aspx" mce_href="http://blogs.msdn.com/jmstall/archive/2005/02/06/368192.aspx"&gt;Blue&lt;/A&gt;) with support for generic variance.&amp;nbsp; If you're interested in more details (including a thorough description of assignment compatibility in the face of generic variance) see the &lt;A href="http://msdn.microsoft.com/net/ECMA/#Working Draft 2.9.1"&gt;draft v2 ECMA specification&lt;/A&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;[Update: Added details about covariant arrays from Jim Miller's CLI book, and pointer to the draft v2 ECMA spec above.]&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;[Update: See my post "&lt;A href="http://blogs.msdn.com/rmbyers/archive/2006/06/01/613690.aspx" mce_href="http://blogs.msdn.com/rmbyers/archive/2006/06/01/613690.aspx"&gt;More on generic variance&lt;/A&gt;" for more details and discussion]&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;[Update: Here's an MSDN article that discusses this as well: &lt;A href="http://msdn2.microsoft.com/en-us/library/ms228359(vs.80).aspx"&gt;http://msdn2.microsoft.com/en-us/library/ms228359(vs.80).aspx&lt;/A&gt;]&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN lang=EN style="mso-ansi-language: EN-CA"&gt;[Update: Anders has &lt;A class="" href="http://channel9.msdn.com/pdc2008/TL16/" mce_href="http://channel9.msdn.com/pdc2008/TL16/"&gt;finally announced&lt;/A&gt; that &lt;A class="" href="http://code.msdn.microsoft.com/csharpfuture" mce_href="http://code.msdn.microsoft.com/csharpfuture"&gt;C# 4.0&lt;/A&gt; and the BCL will support generic variance with "in" and "out" keywords.&amp;nbsp; This has been in the works for awhile, and of course I'm super excited about it.]&lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=375079" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/rmbyers/archive/tags/Languages/default.aspx">Languages</category><category domain="http://blogs.msdn.com/rmbyers/archive/tags/CLR/default.aspx">CLR</category></item><item><title>"Hello world" quiz answers</title><link>http://blogs.msdn.com/rmbyers/archive/2005/02/08/369646.aspx</link><pubDate>Wed, 09 Feb 2005 07:07:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:369646</guid><dc:creator>rmbyers</dc:creator><slash:comments>10</slash:comments><comments>http://blogs.msdn.com/rmbyers/comments/369646.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rmbyers/commentrss.aspx?PostID=369646</wfw:commentRss><description>&lt;p&gt;&lt;a href="http://weblogs.asp.net/autocrat" target="_blank"&gt;Matthew Cosier&lt;/a&gt;&amp;nbsp;was the first person to post correct answers to all my &lt;A href="http://blogs.msdn.com/rmbyers/archive/2005/02/06/368203.aspx"&gt;Hello, World quiz questions&lt;/a&gt;, good work Matthew!&amp;nbsp; Here are the answers with some details and links:&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt; &lt;ol type="1"&gt; &lt;li class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;span lang="EN" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-CA"&gt;System.Console.WriteLine(“Hello World!”)&lt;br /&gt;&lt;/span&gt;&lt;a href="http://msdn.microsoft.com/vbasic/"&gt;Visual Basic .NET&lt;/a&gt;&amp;nbsp;- note the lack of a semi-colon &amp;lt;grin&amp;gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;br /&gt;&lt;/span&gt;&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt; &lt;li class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in left 1.75in"&gt;&lt;span lang="EN" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-CA"&gt;write('Hello world'),nl.&lt;/span&gt; &lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Prolog"&gt;Prolog&lt;/a&gt; - an older (but cool) logic programming language.&amp;nbsp; Prolog makes it incredibly easy to solve certain classes of logic problems (especially constraint satisfaction problems).&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Using a domain-specific language like Prolog for a problem it is good at really makes you recognize the value of being a multi-lingual developer.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;I’ve heard of one project (scheduling) that took a week or so to build in C++, and a few hours to re-implement in Prolog. Unfortunately, I’m not aware of any commercial-grade .NET implementation, but there is an academic Prolog to C# translator called &lt;a href="http://www.dcs.ed.ac.uk/home/jjc/psharp/dlpsharp.html"&gt;P#&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt; &lt;li class="MsoNormal" style="MARGIN: 0in 0in 12pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;span lang="EN" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-CA"&gt;std::cout &amp;lt;&amp;lt; “Hello World!” &amp;lt;&amp;lt; std::endl;&lt;/span&gt;&lt;span lang="EN"&gt; &lt;/span&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/C_Plus_Plus"&gt;C++&lt;/a&gt;, where &lt;a href="http://msdn.microsoft.com/visualc/"&gt;Microsoft Visual C++&lt;/a&gt; with managed extensions is of course the .NET implementation.&lt;span lang="EN" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt; &lt;li class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;span lang="EN" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-CA"&gt;." Hello, world!" CR&lt;br /&gt;&lt;/span&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;&lt;a href="http://en.wikipedia.org/wiki/Forth_programming_language"&gt;Forth&lt;/a&gt; – an older (but not cool) low-level programming language.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;I was forced to write an assignment in Forth in &lt;a href="http://www.cs.uwaterloo.ca/"&gt;University&lt;/a&gt; – an experienced that helped me to truly appreciate the benefits if higher-level languages &amp;lt;grin&amp;gt;.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;a href="http://www.dataman.ro/dforth/default.asp"&gt;Detla Forth .NET&lt;/a&gt; is a shareware .NET implementation.&lt;/span&gt;&lt;span lang="EN" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-CA"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span lang="EN"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt; &lt;li class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;span lang="EN" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-CA"&gt;Ada.Text_IO.Put_Line ("Hello, world!");&lt;br /&gt;&lt;/span&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;&lt;a href="http://en.wikipedia.org/wiki/Ada_programming_language"&gt;Ada&lt;/a&gt; (obviously) – an interesting language which was engineered in the 70s from the ground up (by the &lt;?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /&gt;&lt;st1:country-region w:st="on"&gt;&lt;st1:place w:st="on"&gt;US&lt;/st1:place&gt;&lt;/st1:country-region&gt; department of defence) for building highly-reliable embedded and real-time systems.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;st1:City w:st="on"&gt;Ada&lt;/st1:City&gt; still has a strong following, and I think today’s mainstream languages could benefit a lot from some of the ideas (strong type safety, built-in concurrency support, etc.), championed by &lt;st1:City w:st="on"&gt;&lt;st1:place w:st="on"&gt;Ada&lt;/st1:place&gt;&lt;/st1:City&gt;.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;a href="http://www.usafa.af.mil/dfcs/bios/mcc_html/a_sharp.html"&gt;A#&lt;/a&gt; is an academic project to run &lt;st1:City w:st="on"&gt;&lt;st1:place w:st="on"&gt;Ada&lt;/st1:place&gt;&lt;/st1:City&gt; code on the CLR – although (despite my pride in our product), I wouldn’t suggest you go moving your nuclear missile silo control applications over to running on the CLR &amp;lt;grin&amp;gt;.&lt;/span&gt;&lt;span lang="EN" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-CA"&gt; &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt; &lt;li class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;span lang="EN" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-CA"&gt;ldstr "Hello World!" call void [mscorlib]System.Console::WriteLine(string)&lt;/span&gt;&lt;span lang="EN"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;&lt;a href="http://msdn.microsoft.com/net/ecma/default.asp"&gt;Common Intermediate Language&lt;/a&gt; (CIL/MSIL) – the input to the CLR, and yes IlAsm.exe doesn’t seem to care whether I put a newline in there.&lt;br /&gt;&lt;/span&gt;&lt;span lang="EN" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt; &lt;li class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;span lang="EN" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-CA"&gt;io.put_string("Hello, world!%N")&lt;/span&gt;&lt;span lang="EN"&gt; &lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.eiffel.com/developers/"&gt;Eiffel&lt;/a&gt; – a modern object-oriented language with an emphasis on reliability through the “design by contract” development philosophy.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;In my opinion, there are some very important ideas here (I’m reading Bertrand Meyer’s classic book “&lt;a href="http://www.amazon.com/exec/obidos/tg/detail/-/0136291554"&gt;Object Oriented Software Construction&lt;/a&gt;” now).&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Eiffel is one of the CLR’s most important language partners (some aspects of Generics in Whidbey were added largely for the sake of Eiffel).&lt;br style="mso-special-character: line-break" /&gt;&lt;span lang="EN" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt; &lt;li class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;span lang="EN" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-CA"&gt;System.Console.WriteLine(“Hello World!”);&lt;/span&gt;&lt;span lang="EN"&gt; &lt;/span&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/vcsharp/"&gt;C#&lt;/a&gt; (or J# etc.) &lt;br style="mso-special-character: line-break" /&gt;&lt;span lang="EN" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt; &lt;li class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;span lang="EN" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-CA"&gt;string* s = {yield return "Hello"; yield return "World!";}; s.{Console.WriteLine(it);};&lt;/span&gt;&lt;span lang="EN"&gt; &lt;/span&gt;&lt;br /&gt;&lt;a href="http://research.microsoft.com/comega/"&gt;Cω (Comega)&lt;/a&gt; – An extension to C# from Microsoft Research (based on Xen, X# and polyphonic C#).&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Cω adds powerful support for data access (including integrating SQL and XML) and interesting concurrency abstractions.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Expect to see a number of future blog entries here about Cω.&lt;br /&gt;&lt;span lang="EN" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt; &lt;li class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;span lang="EN" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-CA"&gt;(display "Hello, world!") (newline)&lt;br /&gt;&lt;/span&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;&lt;a href="http://en.wikipedia.org/wiki/Scheme_programming_language"&gt;Scheme&lt;/a&gt; – an older but very simple and elegant functional language.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Every computer-science student should have to write some programs in Scheme (or other variant of Lisp) and read the classic textbook “&lt;a href="http://en.wikipedia.org/wiki/Structure_and_Interpretation_of_Computer_Programs"&gt;The Structure and Interpretation of Computer Programs&lt;/a&gt;” (sadly, I was permitted to graduate without ever reading this elegant text, but I’ve recently corrected that error in my education).&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;The &lt;a href="http://hotdog.sourceforge.net/"&gt;Hotdog scheme compiler&lt;/a&gt; can target .NET.&lt;/span&gt;&lt;span lang="EN" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;If you’ve read this far, then you might be interested in &lt;a href="http://en.wikipedia.org/wiki/Hello_world_program"&gt;this catalog of “Hello World” programs&lt;/a&gt;.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Sadly, I didn’t find it until after I had written most of my quiz &amp;lt;grin&amp;gt;.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;I also like this &lt;a href="http://www.levenez.com/lang/history.html"&gt;Programming Languages Timeline&lt;/a&gt;, and &lt;a href="http://www.dotnetlanguages.net/DNL/Resources.aspx"&gt;here is a list of .NET-based language implementations&lt;/a&gt;.&amp;nbsp; Anyone else have any good links like this?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=369646" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/rmbyers/archive/tags/Languages/default.aspx">Languages</category></item><item><title>Disruptive Programming Language Technologies</title><link>http://blogs.msdn.com/rmbyers/archive/2005/02/06/368216.aspx</link><pubDate>Mon, 07 Feb 2005 04:24:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:368216</guid><dc:creator>rmbyers</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/rmbyers/comments/368216.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rmbyers/commentrss.aspx?PostID=368216</wfw:commentRss><description>&lt;p&gt;"Disruptive Programming Language Technologies" (&lt;a href="http://murl.microsoft.com/LectureDetails.asp?958"&gt;video&lt;/a&gt;, &lt;a href="http://research.microsoft.com/~toddpro/papers/disruptive.ppt"&gt;slides&lt;/a&gt;) is one of my favorite talks on the future of programming languages.&amp;nbsp;The talk is by&amp;nbsp;&lt;a href="http://research.microsoft.com/~toddpro/"&gt;Todd Proebsting&lt;/a&gt;, who&amp;nbsp;is a senior researcher at the &lt;a href="http://www.microsoft.com/windows/cse/default.mspx"&gt;Microsoft Center for Software Excellence&lt;/a&gt;&amp;nbsp;(formerly the &lt;?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /&gt;&lt;st1:place w:st="on"&gt;&lt;st1:PlaceName w:st="on"&gt;Programmer&lt;/st1:PlaceName&gt; &lt;st1:PlaceName w:st="on"&gt;Productivity&lt;/st1:PlaceName&gt; &lt;st1:PlaceName w:st="on"&gt;Research&lt;/st1:PlaceName&gt; &lt;st1:PlaceType w:st="on"&gt;Center&lt;/st1:PlaceType&gt;&lt;/st1:place&gt;).&amp;nbsp; His point applies particularly well to the success of managed environments like .NET.&amp;nbsp; Managed (type-safe, garbage collected) environments have existed in the same basic form for decades, but due to their disadvantages (eg. performance) the mainstream industry&amp;nbsp;largely ignored them.&amp;nbsp; Eventually&amp;nbsp;the industry viewpoint shifted radically, and relatively quickly, to embrace this technology.&amp;nbsp; I find it amusing looking back at my own viewpoint on this subject.&amp;nbsp; I’m ashamed to say that it wasn't that long ago that I thought managed languages like Java and VB were "toy" languages that no real serious programmer would choose to use.&amp;nbsp; Over the past 5 years, my attitude changed radically, even though the technology really didn’t. &lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/span&gt;I've committed myself to not being so narrow-minded about whatever the next big changes are &amp;lt;grin&amp;gt;.&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt; &lt;p&gt;Here's is Todd's summary of this talk:&lt;/p&gt; &lt;blockquote dir="ltr" style="MARGIN-RIGHT: 0px"&gt; &lt;p&gt;For the past few decades, programming language design and implementation research has concentrated heavily in a few notable areas: type theory, functional programming, object-oriented programming, and, of course, optimization techniques. Yet the recent commercially successful languages (e.g., Perl, Python, Visual Basic, Java) are not particularly interesting when judged in these domains. What happened? Each represented a "disruptive technology" that allowed it to capture programmer mindshare while everybody else was looking. In this talk, I will present what I think makes a programming language technology disruptive, and I will propose possible future disruptive programming language technologies.&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=368216" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/rmbyers/archive/tags/Languages/default.aspx">Languages</category></item><item><title>Hello, World!</title><link>http://blogs.msdn.com/rmbyers/archive/2005/02/06/368203.aspx</link><pubDate>Mon, 07 Feb 2005 03:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:368203</guid><dc:creator>rmbyers</dc:creator><slash:comments>10</slash:comments><comments>http://blogs.msdn.com/rmbyers/comments/368203.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rmbyers/commentrss.aspx?PostID=368203</wfw:commentRss><description>&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;Hi, my name is Rick Byers.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;I’m a developer on the &lt;a href="http://msdn.microsoft.com/netframework/programming/clr/default.aspx"&gt;Common Language Runtime&lt;/a&gt; (CLR) team at Microsoft.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;I work on the debugger services team where our main deliverable is the ICorDebug API which debuggers like &lt;a href="http://msdn.microsoft.com/vstudio/"&gt;Visual Studio&lt;/a&gt; use to debug managed code.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;&lt;A href="http://blogs.msdn.com/jmstall"&gt;Mike Stall&lt;/a&gt; already has an awesome ICorDebug blog, so I’m not about to try to compete with him here &amp;lt;grin&amp;gt;.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Instead, I plan on using this space to blab about whatever ideas from the software industry I happen to find exciting at the moment.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;I’ll also try and share some information about the CLR that you might find interesting.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;Mainly, I’m excited about improvements to programmer productivity in the software industry.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Building large and complex pieces of software which are also correct, reliable, secure, robust, maintainable and understandable is incredibly difficult.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;In my opinion, figuring out how to do it better (“engineering” anyone?) is incredibly important.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;I don’t pretend to have any great insights here, but I do try and read and learn what I can in this area, so I’ll often pass on tidbits of information and research which I think are exciting and important.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;My favourite areas are the design of programming languages and developer tools.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;Of course, the CLR (and managed type-safe environments in general) is all about improving developer productivity (which is primarily why I joined this team).&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;The CLR also makes it easier to experiment with and deploy new programming languages.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;On that note, let’s get things started off with a little quiz.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Which language is each of the following code snippets written in?&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Here’s a hint, there are .NET implementations for all of them.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt"&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;ol style="MARGIN-TOP: 0in" type="1"&gt; &lt;li class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;&lt;font face="Courier New"&gt;&lt;font size="2"&gt;System.Console.WriteLine(“Hello World!”)&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;li class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;&lt;font face="Courier New"&gt;&lt;font size="2"&gt;write('Hello world'),nl.&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;li class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;&lt;font face="Courier New"&gt;&lt;font size="2"&gt;std::cout &amp;lt;&amp;lt; “Hello World!” &amp;lt;&amp;lt; std::endl;&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;li class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;&lt;font face="Courier New"&gt;&lt;font size="2"&gt;." Hello, world!" CR&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;li class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;&lt;font face="Courier New"&gt;&lt;font size="2"&gt;Ada.Text_IO.Put_Line ("Hello, world!");&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;li class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;&lt;font face="Courier New"&gt;&lt;font size="2"&gt;ldstr "Hello World!" call void [mscorlib]System.Console::WriteLine(string)&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;li class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;&lt;font face="Courier New"&gt;&lt;font size="2"&gt;io.put_string("Hello, world!%N")&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;li class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;&lt;font face="Courier New"&gt;&lt;font size="2"&gt;System.Console.WriteLine(“Hello World!”);&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;li class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;&lt;font face="Courier New"&gt;&lt;font size="2"&gt;string* s = {yield return "Hello"; yield return "World!";}; s.{Console.WriteLine(it);};&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;li class="MsoNormal" style="MARGIN: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list .5in"&gt;&lt;span lang="EN" style="mso-ansi-language: EN-CA"&gt;&lt;font face="Courier New"&gt;&lt;font size="2"&gt;(display "Hello, world!") (newline)&lt;o:p&gt;&lt;/o:p&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=368203" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/rmbyers/archive/tags/Languages/default.aspx">Languages</category></item></channel></rss>