<?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>jaredpar's WebLog : Generics</title><link>http://blogs.msdn.com/jaredpar/archive/tags/Generics/default.aspx</link><description>Tags: Generics</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Immutable Collections and Compatibility with Existing Frameworks</title><link>http://blogs.msdn.com/jaredpar/archive/2008/12/10/immutable-collections-and-backwards-compatibility.aspx</link><pubDate>Wed, 10 Dec 2008 16:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9187707</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/9187707.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=9187707</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=9187707</wfw:comment><description>&lt;P&gt;When developing my &lt;A href="http://code.msdn.microsoft.com/RantPack" mce_href="http://code.msdn.microsoft.com/RantPack"&gt;immutable collections library&lt;/A&gt;, I spent a lot of time on usability.&amp;nbsp; After all, if a library is not useful then what’s the point?&lt;/P&gt;
&lt;P&gt;A big portion of usability is being able to work with existing frameworks and technologies.&amp;nbsp; For .Net and collections that means items like Data binding, LINQ etc …&amp;nbsp; Without integrating into popular technologies the usefulness of a particular library is severely impacted and hence usability decreases.&lt;/P&gt;
&lt;P&gt;Most of the existing collection based infrastructures use the .Net collection interfaces as their form of abstraction.&amp;nbsp; The most straight forward way to ensure compatibility is to implement these interfaces on the collections in question.&amp;nbsp; In particular &lt;A href="http://msdn.microsoft.com/en-us/library/92t2ye13.aspx" mce_href="http://msdn.microsoft.com/en-us/library/92t2ye13.aspx"&gt;ICollection&amp;lt;T&amp;gt;&lt;/A&gt;, &lt;A href="http://msdn.microsoft.com/en-us/library/5y536ey6.aspx" mce_href="http://msdn.microsoft.com/en-us/library/5y536ey6.aspx"&gt;IList&amp;lt;T&amp;gt;&lt;/A&gt; and &lt;A href="http://msdn.microsoft.com/en-us/library/9eekhta0.aspx" mce_href="http://msdn.microsoft.com/en-us/library/9eekhta0.aspx"&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/A&gt; are the main abstractions.&amp;nbsp; Lets investigate which ones an Immutable collection should be implementing in order to effectively integrate into existing collection based infrastructures.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;This is the easiest decision.&amp;nbsp; IEnumerable&amp;lt;T&amp;gt; represents a read only, one element at time view on a sequence of objects.&amp;nbsp; Immutable collections can easily and reliably implement a IEnumerable&amp;lt;T&amp;gt;.&amp;nbsp; This is a no brainer.&amp;nbsp; Implement.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;ICollection&amp;lt;T&amp;gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;This interfaces represents a general collection class.&amp;nbsp; Unfortunately this interface is meant to represent a mutable collection class and implements such methods as Add, Clear and Remove.&amp;nbsp; These methods cannot be implemented on an Immutable collection given the current design.&amp;nbsp; All three of these methods are void returning methods because the collection is meant to be changed in place.&amp;nbsp; Immutable collections can support these operations but it involves returning a new instance of the collection.&amp;nbsp; &lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public sealed class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ImmutableCollection&lt;/SPAN&gt;&amp;lt;T&amp;gt; : &lt;SPAN style="COLOR: #2b91af"&gt;ICollection&lt;/SPAN&gt;&amp;lt;T&amp;gt; {
    &lt;SPAN style="COLOR: blue"&gt;public &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ImmutableCollection&lt;/SPAN&gt;&amp;lt;T&amp;gt; Add(T item) {
        &lt;SPAN style="COLOR: green"&gt;// Actually add 
        // ...
    &lt;/SPAN&gt;}

    &lt;SPAN style="COLOR: blue"&gt;#region &lt;/SPAN&gt;ICollection&amp;lt;T&amp;gt; Members

    &lt;SPAN style="COLOR: blue"&gt;void &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ICollection&lt;/SPAN&gt;&amp;lt;T&amp;gt;.Add(T item) {
        &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;created = &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.Add(item);
        &lt;SPAN style="COLOR: green"&gt;// What to do with created???
    &lt;/SPAN&gt;}

    ...
}&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;But wait!&amp;nbsp; The interface does support a property named &lt;A href="http://msdn.microsoft.com/en-us/library/0cfatk9t.aspx" mce_href="http://msdn.microsoft.com/en-us/library/0cfatk9t.aspx"&gt;IsReadOnly&lt;/A&gt;.&amp;nbsp; The intention of this property is to allow an interface to programmatically declare they do not support modifications.&amp;nbsp; A read only collection can just implement this interface, throw a&amp;nbsp;&lt;A class="" title=NotSupportedException href="http://msdn.microsoft.com/en-us/library/system.notsupportedexception.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.notsupportedexception.aspx"&gt;NotSupportedException&lt;/A&gt; for all of the mutable methods and return true for IsReadOnly and presto we have a suitable interface for an immutable collection.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Or do we?&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The design for ICollection&amp;lt;T&amp;gt; with respect to read only or immutable collections is not optimal.&amp;nbsp; It attempts to combine to separate behaviors into a single interface: mutable and readonly view of a collection.&amp;nbsp; Dual purpose interfaces run into problems because it’s impossible to separate out the behaviors at compile time.&amp;nbsp; This is especially problematic when the behaviors are conflicting.&amp;nbsp; There is no way a read only collection can prevent itself from being passed to a function that expects a mutable collection at compile time.&amp;nbsp; Nor can a consumer who intends to mutate a collection prevent a read-only collection from being passed. &lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;static void &lt;/SPAN&gt;DisplayForEdit&amp;lt;T&amp;gt;(&lt;SPAN style="COLOR: #2b91af"&gt;ICollection&lt;/SPAN&gt;&amp;lt;T&amp;gt; col) {
    &lt;SPAN style="COLOR: green"&gt;// ...
    &lt;/SPAN&gt;m_clearButton.Click += (x, y) =&amp;gt; col.Clear(); 
}

&lt;SPAN style="COLOR: blue"&gt;static void &lt;/SPAN&gt;Example1() {
    &lt;SPAN style="COLOR: #2b91af"&gt;ImmutableCollection&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;&amp;gt; col = &lt;SPAN style="COLOR: #2b91af"&gt;ImmutableCollection&lt;/SPAN&gt;.Create(&lt;SPAN style="COLOR: blue"&gt;new int&lt;/SPAN&gt;[] { 1, 2, 3, 4 });
    DisplayForEdit(col);    &lt;SPAN style="COLOR: green"&gt;// Will fail as soon as Clear is clicked
&lt;/SPAN&gt;}&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;But isn’t it the responsibility of the user of ICollection&amp;lt;T&amp;gt; to verify that IsReadOnly is false before mutating a instance?&amp;nbsp; Given the current design of ICollection&amp;lt;T&amp;gt; it is indeed both the responsibility of the consumer to verify this and the implementer to ensure they are not called incorrectly.&amp;nbsp; The problem with putting responsibility on the consumer though is they have to 1) know about read only uses of ICollection&amp;lt;T&amp;gt; and 2) actually care about it.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;A quick search of the BCL with reflector can give us evidence of how much consumers actually check for the read only scenario.&amp;nbsp; For the search I used mscorlib, System, System.Xml, System.Data, System.Drawing and System.Core and System.Windows.Forms.&amp;nbsp; And the number of classes which actually take into account ICollection&amp;lt;T&amp;gt;.IsReadOnly is … 1.&amp;nbsp; System.Collections.ObjectModel.Collection&amp;lt;T&amp;gt;.&amp;nbsp; That’s it.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;So even if an immutable collection implements this interface in a read-only fashion there’s little chance anyone will be checking for it.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;IList&amp;lt;T&amp;gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;IList&amp;lt;T&amp;gt; inherits from ICollection&amp;lt;T&amp;gt; and hence suffers from all of the same problems&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Decision Time&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;In order to facilitate usability with existing frameworks immutable collections are forced to implement interfaces for which they have no possible way of implementing properly.&amp;nbsp; If collections implement these interfaces they will be trading usability for compile time validation.&amp;nbsp; Even worse is the conversion is implicit which prevents even basic searches for places this conversion occurs.&amp;nbsp; This is a heavy price to pay for compatibility. &lt;/P&gt;
&lt;P&gt;After debating this for awhile I decided that loss of compile time validation was a too heavy of a price to pay for the default scenario.&amp;nbsp; But trading away usability was also unacceptable.&amp;nbsp; As a compromise I opted for adding a compatibility layer to the collections.&amp;nbsp; Instead of implementing the ICollection&amp;lt;T&amp;gt; and IList&amp;lt;T&amp;gt; collections directly I created a set of proxy objects that implement the interfaces on behalf of the immutable collections.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;In order to centralize this effort I created a factory class, CollectionUtility, which contains appropriate overloads for all of my immutable collection classes [1].&amp;nbsp; &lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public static class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;CollectionUtility &lt;/SPAN&gt;{
    &lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;T&amp;gt; CreateEmptyEnumerable&amp;lt;T&amp;gt;();
    &lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;T&amp;gt; CreateEnumerable&amp;lt;T&amp;gt;(T value);
&lt;SPAN style="COLOR: green"&gt;    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ICollection&lt;/SPAN&gt;&amp;lt;T&amp;gt; CreateICollection&amp;lt;T&amp;gt;(&lt;SPAN style="COLOR: #2b91af"&gt;IReadOnlyCollection&lt;/SPAN&gt;&amp;lt;T&amp;gt; col);
    &lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;IDictionary&lt;/SPAN&gt;&amp;lt;TKey, TValue&amp;gt; CreateIDictionary&amp;lt;TKey, TValue&amp;gt;(&lt;SPAN style="COLOR: #2b91af"&gt;IReadOnlyMap&lt;/SPAN&gt;&amp;lt;TKey, TValue&amp;gt; map);
&lt;SPAN style="COLOR: green"&gt;    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;IList&lt;/SPAN&gt;&amp;lt;T&amp;gt; CreateIList&amp;lt;T&amp;gt;(&lt;SPAN style="COLOR: #2b91af"&gt;IReadOnlyList&lt;/SPAN&gt;&amp;lt;T&amp;gt; list);
    &lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ICollection &lt;/SPAN&gt;CreateObjectICollection&amp;lt;T&amp;gt;(&lt;SPAN style="COLOR: #2b91af"&gt;IReadOnlyCollection&lt;/SPAN&gt;&amp;lt;T&amp;gt; col);
    &lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;IDictionary &lt;/SPAN&gt;CreateObjectIDictionary&amp;lt;TKey, TValue&amp;gt;(&lt;SPAN style="COLOR: #2b91af"&gt;IReadOnlyMap&lt;/SPAN&gt;&amp;lt;TKey, TValue&amp;gt; map);
    &lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;IList &lt;/SPAN&gt;CreateObjectIList&amp;lt;T&amp;gt;(&lt;SPAN style="COLOR: #2b91af"&gt;IReadOnlyList&lt;/SPAN&gt;&amp;lt;T&amp;gt; list);
    &lt;SPAN style="COLOR: blue"&gt;public 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; GetRangeCount(&lt;SPAN style="COLOR: blue"&gt;int &lt;/SPAN&gt;start, &lt;SPAN style="COLOR: blue"&gt;int &lt;/SPAN&gt;count);
}&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;The proxy objects live as private inner classes inside CollectionUtility.&amp;nbsp; They implement the collection interfaces in the most read-only way possible.&amp;nbsp; When confronted with mutating calls, the proxies throw &lt;A class="" title=NotSupportedException href="http://msdn.microsoft.com/en-us/library/system.notsupportedexception.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.notsupportedexception.aspx"&gt;NotSupportedException&lt;/A&gt;.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;So at the end of the day I have compile time validation for immutable collections.&amp;nbsp; If a developer wants to use them in a less than safe scenario it requires an explicit conversion.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;static void &lt;/SPAN&gt;Example2() { 
  &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;col = &lt;SPAN style="COLOR: #2b91af"&gt;ImmutableCollection&lt;/SPAN&gt;.Create(&lt;SPAN style="COLOR: blue"&gt;new int&lt;/SPAN&gt;[] { 1, 2, 3, 4 }); 
  &lt;SPAN style="COLOR: green"&gt;// Still fails, but explicit conversion required 
  &lt;/SPAN&gt;DisplayForEdit(&lt;SPAN style="COLOR: #2b91af"&gt;CollectionUtility&lt;/SPAN&gt;.CreateICollection(col)); 
  }&lt;/PRE&gt;
&lt;P&gt;I feel like this as an appropriate tradeoff.&amp;nbsp;&amp;nbsp; In the worst case scenario, a developer can search for all accesses of the CollectionUtility class and find places where a proxy is being created.&lt;/P&gt;
&lt;P&gt;Next time, lets take a look at a different way of approaching an interface hierarchy for a set of collections.&amp;nbsp; One that will allow us to avoid this problem altogether going forward.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;[1] It actually contains overloads for a set of truly read only collection interfaces that I wrote for my library but we’ll get to that another time.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Edit: Updated the exception to be NotSupportedException&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9187707" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Generics/default.aspx">Generics</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Immutable/default.aspx">Immutable</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/API+Design/default.aspx">API Design</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/RantPack/default.aspx">RantPack</category></item><item><title>Gotcha: Generic overload resolution when called generically</title><link>http://blogs.msdn.com/jaredpar/archive/2008/04/14/gotcha-generic-overload-resolution-when-called-generically.aspx</link><pubDate>Mon, 14 Apr 2008 15:30:07 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8381274</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/8381274.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=8381274</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=8381274</wfw:comment><description>&lt;p&gt;Both VB and C# have a feature of generic overload resolution that is fairly helpful and yet a source of gotchas.&amp;nbsp; Lets say you have two methods with the same number of arguments.&amp;nbsp; One method has arguments with generic types and the other does not.&amp;nbsp; For Example:&lt;/p&gt;&lt;pre class="code"&gt;    &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;C1&lt;/span&gt;&amp;lt;T&amp;gt; {
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; F1(&lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt; ival) {
            &lt;span style="color: rgb(43,145,175)"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(163,21,21)"&gt;"Non-generic F1"&lt;/span&gt;);
        }
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; F1(T val) {
            &lt;span style="color: rgb(43,145,175)"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(163,21,21)"&gt;"Generic F1"&lt;/span&gt;);
        }
    }&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Imagine what happens when we have a C1&amp;lt;int&amp;gt; and call F1(5).&amp;nbsp; Which method should the compiler bind to?&amp;nbsp; Both VB and C# when presented with this type of situation will choose the non-generic version.&amp;nbsp; &lt;/p&gt;&lt;pre class="code"&gt;            v1.F1(5);           &lt;span style="color: rgb(0,128,0)"&gt;// Binds to Non-generic F1
&lt;/span&gt;            v2.F1(&lt;span style="color: rgb(163,21,21)"&gt;"foo"&lt;/span&gt;);       &lt;span style="color: rgb(0,128,0)"&gt;// Binds to Generic F1&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;At a glance we might think that we can provide specialized behavior for a subset of types that are interesting (similar to C++ template specialization).&amp;nbsp; If VB/C# will bind to our non-generic version then we don't have to due ugly type switching to implement different behavior for certain types.&amp;nbsp; Unfortunately we would be wrong.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;This type of overload resolution only happens if the compiler can statically verify that the argument matches a non-generic overload.&amp;nbsp; So if we call F1 generically it will not bind to the non-generic overload.&amp;nbsp; &lt;/p&gt;&lt;pre class="code"&gt;        &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; TestOverload&amp;lt;T&amp;gt;(&lt;span style="color: rgb(43,145,175)"&gt;C1&lt;/span&gt;&amp;lt;T&amp;gt; weird, T value) {
            weird.F1(value);
        }

        &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; Main(&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;[] args) {
            &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; v1 = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;C1&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt;&amp;gt;();
            &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; v2 = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;C1&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;&amp;gt;();

            TestOverload(v1, 5);        &lt;span style="color: rgb(0,128,0)"&gt;// Binds to Generic F1
&lt;/span&gt;            TestOverload(v2, &lt;span style="color: rgb(163,21,21)"&gt;"foo"&lt;/span&gt;);    &lt;span style="color: rgb(0,128,0)"&gt;// Binds to Generic F1
&lt;/span&gt;        }&lt;/pre&gt;&lt;pre class="code"&gt;&amp;nbsp;&lt;/pre&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8381274" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Generics/default.aspx">Generics</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Gotcha/default.aspx">Gotcha</category></item><item><title>Design Guidelines: Provide type inference friendly Create function for generic objects</title><link>http://blogs.msdn.com/jaredpar/archive/2008/04/11/design-guidelines-provide-type-inference-friendly-create-function-for-generic-objects.aspx</link><pubDate>Fri, 11 Apr 2008 15:24:50 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8363462</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/8363462.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=8363462</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=8363462</wfw:comment><description>&lt;p&gt;Really this guideline is a bit longer but putting it all in a blog title seemed a bit too much.&amp;#160; The full guideline should read: &amp;quot;If a generic class constructor arguments contain types of all generic parameters, provide a static method named Create on a static class of the same class name as the generic class which takes the same arguments and calls the constructor.&amp;quot;&amp;#160; Quite a mouth full.&amp;#160; &lt;/p&gt;  &lt;p&gt;Lets look at a specific example with &lt;a href="http://blogs.msdn.com/jaredpar/archive/2008/01/27/tuples-part-8-finishing-up.aspx"&gt;Tuples&lt;/a&gt;.&amp;#160; Tuples are generic with respect to the values they are representing.&amp;#160; Without any type inference help we would have to write the following code to create a simple tuple. &lt;/p&gt;  &lt;pre class="code"&gt;            &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; tuple = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Tuple&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt;, &lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;&amp;gt;(5, &lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;astring&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

&lt;p&gt;Not too bad because we are using simple types.&amp;#160; But what happens when we are using really long type names?&amp;#160; &lt;/p&gt;

&lt;pre class="code"&gt;            &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; tuple2 = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Tuple&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;,&lt;span style="color: rgb(43,145,175)"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;, &lt;span style="color: rgb(43,145,175)"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt;&amp;gt;&amp;gt;&amp;gt;(val1, val2);&lt;/pre&gt;

&lt;p&gt;As we can see, the code is getting quite a bit uglier.&amp;#160; This pattern is in fact not maintainable once we start using un-namable types such as anonymous types or generics of anonymous types.&amp;#160; &lt;/p&gt;

&lt;p&gt;The problem here is we are not leveraging the compilers type inference capabilities.&amp;#160; The compiler can easily infer the types of a tuple argument and hence create a tuple.&amp;#160; We just need to provide a mechanism to do so.&amp;#160; The best way is to define a static method on a static class with the same name as the generic.&amp;#160; Lets call this method Create.&lt;/p&gt;

&lt;pre class="code"&gt;    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Tuple&lt;/span&gt; {
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Tuple&lt;/span&gt;&amp;lt;TA, TB&amp;gt; Create&amp;lt;TA, TB&amp;gt;(TA valueA, TB valueB) { 
            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Tuple&lt;/span&gt;&amp;lt;TA, TB&amp;gt;(valueA, valueB); 
        }
    }&lt;/pre&gt;

&lt;p&gt;The method Tuple.Create still has two generic parameters.&amp;#160; However since we are providing a set of values which contain types for every generic parameter, the compiler can infer the generic arguments.&amp;#160; Now we can create a Tuple without specifying any generic arguments.&amp;#160; Because no types are specified this will work with any value in the code including un-namable types.&amp;#160; &lt;/p&gt;

&lt;pre class="code"&gt;            &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; tuple = &lt;span style="color: rgb(43,145,175)"&gt;Tuple&lt;/span&gt;.Create(6, &lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;astring&amp;quot;&lt;/span&gt;);
            &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; tuple2 = &lt;span style="color: rgb(43,145,175)"&gt;Tuple&lt;/span&gt;.Create(6, &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; { name = &lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;aname&amp;quot;&lt;/span&gt;, value = 42 });&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8363462" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Generics/default.aspx">Generics</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Type+Inference/default.aspx">Type Inference</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/API+Design/default.aspx">API Design</category></item><item><title>Have an IComparer&lt;T&gt; but need an IComparable&lt;T&gt;?</title><link>http://blogs.msdn.com/jaredpar/archive/2008/04/09/have-an-icomparer-t-but-need-an-icomparable-t.aspx</link><pubDate>Wed, 09 Apr 2008 15:20:59 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8362118</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/8362118.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=8362118</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=8362118</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/jaredpar/archive/2008/04/02/have-a-icomparable-of-t-but-need-an-icomparer-of-t.aspx"&gt;Previously&lt;/a&gt; we discussed the opposite problem.&amp;#160; This is a lesser but often more frustrating problem because there is no, AFAIK, built in solution for the BCL.&amp;#160; However it's problem that can be solved once and reused with a generic solution. IComparable&amp;lt;T&amp;gt; has all of the methods necessary implement IComparer&amp;lt;T&amp;gt;.&amp;#160; &lt;/p&gt;  &lt;p&gt;To work around this we'll create a new class that can wrap both a value and an instance of IComparable(Of T).&amp;#160; Lets call it ComparerNode&amp;lt;T&amp;gt;.&amp;#160; This class can be used wherever an IComparable&amp;lt;T&amp;gt; is needed.&amp;#160; &lt;/p&gt;  &lt;p&gt;Unfortunately generic classes will not provide a 1:1 mapping.&amp;#160; However getting to the actual data is strongly typed and comes through a simple property.&amp;#160; &lt;/p&gt;  &lt;pre class="code"&gt;   &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;sealed&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ComparerNode&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style="color: rgb(43,145,175)"&gt;IComparable&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;ComparerNode&lt;/span&gt;&amp;lt;T&amp;gt;&amp;gt; {
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;IComparer&lt;/span&gt;&amp;lt;T&amp;gt; m_comparer;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; T m_value;

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;IComparer&lt;/span&gt;&amp;lt;T&amp;gt; Comparer {
            &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt; { &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; m_comparer; }
        }

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; T Value {
            &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt; { &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; m_value; }
        }

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; ComparerNode(&lt;span style="color: rgb(43,145,175)"&gt;IComparer&lt;/span&gt;&amp;lt;T&amp;gt; comparer, T value) {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (comparer == &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;) {
                &lt;span style="color: rgb(0,0,255)"&gt;throw&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ArgumentNullException&lt;/span&gt;(&lt;span style="color: rgb(163,21,21)"&gt;&amp;quot;comparer&amp;quot;&lt;/span&gt;);
            }

            m_comparer = comparer;
            m_value = value;
        }

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;override&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt; GetHashCode() {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (m_value == &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;) {
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 0;
            }

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; m_value.GetHashCode();
        }

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;override&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;bool&lt;/span&gt; Equals(&lt;span style="color: rgb(0,0,255)"&gt;object&lt;/span&gt; obj) {
            &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; other = obj &lt;span style="color: rgb(0,0,255)"&gt;as&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ComparerNode&lt;/span&gt;&amp;lt;T&amp;gt;;
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (other == &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;) {
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;false&lt;/span&gt;;
            }

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 0 == m_comparer.Compare(m_value, other.m_value);
        }

&lt;span style="color: rgb(0,0,255)"&gt;        #region&lt;/span&gt; IComparable&amp;lt;ComparerNode&amp;lt;T&amp;gt;&amp;gt; Members

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt; CompareTo(&lt;span style="color: rgb(43,145,175)"&gt;ComparerNode&lt;/span&gt;&amp;lt;T&amp;gt; other) {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (other == &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;) {
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 1;
            }

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; m_comparer.Compare(m_value, other.m_value);
        }

&lt;span style="color: rgb(0,0,255)"&gt;        #endregion

&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;bool&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;operator&lt;/span&gt; &amp;lt;(&lt;span style="color: rgb(43,145,175)"&gt;ComparerNode&lt;/span&gt;&amp;lt;T&amp;gt; left, &lt;span style="color: rgb(43,145,175)"&gt;ComparerNode&lt;/span&gt;&amp;lt;T&amp;gt; right) {
            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Comparer&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;ComparerNode&lt;/span&gt;&amp;lt;T&amp;gt;&amp;gt;.Default.Compare(left, right) &amp;lt; 0;
        }

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;bool&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;operator&lt;/span&gt; &amp;gt;(&lt;span style="color: rgb(43,145,175)"&gt;ComparerNode&lt;/span&gt;&amp;lt;T&amp;gt; left, &lt;span style="color: rgb(43,145,175)"&gt;ComparerNode&lt;/span&gt;&amp;lt;T&amp;gt; right) {
            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Comparer&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;ComparerNode&lt;/span&gt;&amp;lt;T&amp;gt;&amp;gt;.Default.Compare(left, right) &amp;gt; 0;
        }

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;bool&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;operator&lt;/span&gt; ==(&lt;span style="color: rgb(43,145,175)"&gt;ComparerNode&lt;/span&gt;&amp;lt;T&amp;gt; left, &lt;span style="color: rgb(43,145,175)"&gt;ComparerNode&lt;/span&gt;&amp;lt;T&amp;gt; right) {
            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;EqualityComparer&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;ComparerNode&lt;/span&gt;&amp;lt;T&amp;gt;&amp;gt;.Default.Equals(left, right);
        }

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;bool&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;operator&lt;/span&gt; !=(&lt;span style="color: rgb(43,145,175)"&gt;ComparerNode&lt;/span&gt;&amp;lt;T&amp;gt; left, &lt;span style="color: rgb(43,145,175)"&gt;ComparerNode&lt;/span&gt;&amp;lt;T&amp;gt; right) {
            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; !&lt;span style="color: rgb(43,145,175)"&gt;EqualityComparer&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;ComparerNode&lt;/span&gt;&amp;lt;T&amp;gt;&amp;gt;.Default.Equals(left, right);
        }
    }

    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ComparerNode&lt;/span&gt; {
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ComparerNode&lt;/span&gt;&amp;lt;T&amp;gt; Create&amp;lt;T&amp;gt;(&lt;span style="color: rgb(43,145,175)"&gt;IComparer&lt;/span&gt;&amp;lt;T&amp;gt; comparer, T value) {
            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ComparerNode&lt;/span&gt;&amp;lt;T&amp;gt;(comparer, value);
        }

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ComparerNode&lt;/span&gt;&amp;lt;T&amp;gt; Create&amp;lt;T&amp;gt;(T value)
            &lt;span style="color: rgb(0,0,255)"&gt;where&lt;/span&gt; T : &lt;span style="color: rgb(43,145,175)"&gt;IComparable&lt;/span&gt;&amp;lt;T&amp;gt; {
            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ComparerNode&lt;/span&gt;&amp;lt;T&amp;gt;(&lt;span style="color: rgb(43,145,175)"&gt;Comparer&lt;/span&gt;&amp;lt;T&amp;gt;.Default, value);
        }
    }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8362118" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Generics/default.aspx">Generics</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Patterns/default.aspx">Patterns</category></item><item><title>Tuples Part 8: Finishing up</title><link>http://blogs.msdn.com/jaredpar/archive/2008/01/27/tuples-part-8-finishing-up.aspx</link><pubDate>Mon, 28 Jan 2008 05:37:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7278167</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/7278167.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=7278167</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=7278167</wfw:comment><description>&lt;p&gt;There are only a few missing features from our tuple implementation.&amp;#160; Mainly FxCop compliance, debugging support and test case code.&amp;#160; The actual functional work is complete.&amp;#160; &lt;/p&gt;  &lt;p&gt;The one issue with FxCop compliance is the chosen names.&amp;#160; Namely using A,B etc.&amp;#160; FxCop, rightly, believes names should have more value.&amp;#160; Accordingly, calling the generic argument corresponding to A, TA also causes the same issue.&amp;#160; This is a design decision made from the &lt;a href="http://blogs.msdn.com/jaredpar/archive/2008/01/03/tuples-part-1.aspx"&gt;begining&lt;/a&gt;.&amp;#160; I don't believe changing the name to ValueA adds any more value than simply A.&amp;#160; Therefore the warning for this will simply be suppressed. &lt;/p&gt;  &lt;p&gt;Additionally FxCop doesn't like types with more than 3 generic parameters.&amp;#160; This is also a design decision intentionally done and there is no avoiding it.&amp;#160; It will be suppressed as well.&amp;#160; &lt;/p&gt;  &lt;p&gt;For debugging support a simple &lt;a href="http://msdn2.microsoft.com/en-us/library/x810d419.aspx"&gt;DebuggerDisplay attribute&lt;/a&gt; will be used.&amp;#160; It will display the current value of all of the tuple values.&amp;#160; &lt;/p&gt;  &lt;p&gt;Here is the latest version of the full script which includes all of the new information.&amp;#160; With the exception of a few small tweaks this is just the combination of the individual parts specified throughout these postings.&lt;/p&gt;  &lt;p&gt;param ( [int]$tupleCount = 5,   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [string]$namespace = &amp;quot;Tuples&amp;quot; ) &lt;/p&gt;  &lt;p&gt;$script:scriptPath = split-path -parent $MyInvocation.MyCommand.Definition    &lt;br /&gt;$script:lowerList = 0..25 | %{ [char]([int][char]'a'+$_) }    &lt;br /&gt;$script:upperList = 0..25 | %{ [char]([int][char]'A'+$_) }    &lt;br /&gt;$script:valueList = &amp;quot;1&amp;quot;,&amp;quot;42&amp;quot;,'&amp;quot;bar&amp;quot;', '&amp;quot;foo&amp;quot;', 'true' &lt;/p&gt;  &lt;p&gt;function script:Gen-FxCop   &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; param ( [int]$code ) &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; switch ( $code )   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 1704 { '[SuppressMessage(&amp;quot;Microsoft.Naming&amp;quot;, &amp;quot;CA1704&amp;quot;)]'; break }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 1005 { '[SuppressMessage(&amp;quot;Microsoft.Design&amp;quot;, &amp;quot;CA1005&amp;quot;)]'; break }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; default: {$(throw &amp;quot;Invalid&amp;quot;)}    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;} &lt;/p&gt;  &lt;p&gt;function script:Gen-Display   &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; param ( [int]$count )    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $OFS = &amp;quot;, &amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $p = [string](0..($count-1) | %{ &amp;quot;{0}={{{0}}}&amp;quot; -f $upperList[$_] })    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; '[DebuggerDisplay(&amp;quot;{0}&amp;quot;)]' -f $p    &lt;br /&gt;} &lt;/p&gt;  &lt;p&gt;function script:Gen-Property   &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; param ( [int] $index&amp;#160; = $(throw &amp;quot;Need an index&amp;quot;), [bool]$mutable = $false) &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; if (-not $mutable )   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;@&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; private readonly T{0} m_{1};    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $(Gen-FxCop 1704)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public T{0} {0} {{ get {{ return m_{1}; }} }} &lt;/p&gt;  &lt;p&gt;&amp;quot;@ -f $upperList[$index],$lowerList[$index]   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; else    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;@&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; private T{0} m_{1};    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $(Gen-FxCop 1704)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public T{0} {0} {{ get {{ return m_{1}; }} set {{ m_{1} = value; }} }} &lt;/p&gt;  &lt;p&gt;&amp;quot;@ -f $upperList[$index],$lowerList[$index]   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;} &lt;/p&gt;  &lt;p&gt;function script:Gen-Constructor   &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; param ( [int] $count = $(throw &amp;quot;Need a count&amp;quot;), [string]$className )    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $OFS = ','    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $list = [string](0..$($count-1) | %{ &amp;quot;T{0} value{0}&amp;quot; -f $upperList[$_]})    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public $className($list) {&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; 0..($count-1) | %{ &amp;quot;m_{0} = value{1};&amp;quot; -f $lowerList[$_],$upperList[$_] }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;}&amp;quot;    &lt;br /&gt;} &lt;/p&gt;  &lt;p&gt;function script:Gen-InferenceConstructor   &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; param ( [int] $count = $(throw &amp;quot;Need a count&amp;quot;), [string]$name )    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $OFS = ','    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $gen = &amp;quot;&amp;lt;&amp;quot; + [string](0..($count-1) | %{ &amp;quot;T&amp;quot;+$upperList[$_] }) + &amp;quot;&amp;gt;&amp;quot;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $list = [string](0..$($count-1) | %{ &amp;quot;T{0} value{0}&amp;quot; -f $upperList[$_] })    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $argList = [string](0..$($count-1) | %{ &amp;quot;value{0}&amp;quot; -f $upperList[$_] })    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public static partial class $name {&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Gen-FxCop 1704    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public static $name$gen Create$gen($list) { return new $name$gen($argList); } &amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;}&amp;quot;    &lt;br /&gt;} &lt;/p&gt;  &lt;p&gt;function script:Gen-Equals   &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; param ( [int] $count = $(throw &amp;quot;Need a count&amp;quot;), [string]$name )    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $OFS = ','    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $gen = &amp;quot;&amp;lt;&amp;quot; + [string](0..($count-1) | %{ &amp;quot;T&amp;quot;+$upperList[$_] }) + &amp;quot;&amp;gt;&amp;quot;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public override bool Equals(object obj) { &amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;return Equals(obj as $name$gen); }&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public bool Equals($name$gen other) {&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;if ( Object.ReferenceEquals(other,null) ) { return false; }&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;if (&amp;quot;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $OFS = &amp;quot;&amp;amp;&amp;amp;&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [string](0..($count-1) | %{&amp;quot;EqualityComparer&amp;lt;T{0}&amp;gt;.Default.Equals(m_{1},other.m_{1})&amp;quot; -f $upperList[$_],$lowerList[$_] })    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;) { return true; }&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;return false;&amp;quot;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;}&amp;quot;    &lt;br /&gt;} &lt;/p&gt;  &lt;p&gt;function script:Gen-GetHashCode   &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; param ( [int] $count = $(throw &amp;quot;Need a count&amp;quot;) )    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public override int GetHashCode() {&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;int code = 0;&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; 0..($count-1) | %{ &amp;quot;code += EqualityComparer&amp;lt;T{0}&amp;gt;.Default.GetHashCode(m_{1});&amp;quot; -f $upperList[$_],$lowerList[$_] }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;return code;&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;}&amp;quot;    &lt;br /&gt;} &lt;/p&gt;  &lt;p&gt;function script:Gen-ITuple   &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; param ( [int] $count = $(throw &amp;quot;Need a count&amp;quot;) )    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $OFS = ','    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $gen = &amp;quot;&amp;lt;&amp;quot; + [string](0..($count-1) | %{ &amp;quot;T&amp;quot;+$upperList[$_] }) + &amp;quot;&amp;gt;&amp;quot;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $base = &amp;quot;&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if ( $count -ne 1 )    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $baseGen = &amp;quot;&amp;lt;&amp;quot; + [string](0..($count-2) | %{ &amp;quot;T&amp;quot;+$upperList[$_] }) + &amp;quot;&amp;gt;&amp;quot;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $base = &amp;quot;: ITuple$baseGen&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; else    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $base = &amp;quot;: ITuple&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Gen-FxCop 1704    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if ( $count -gt 2 ) { Gen-FxCop 1005 }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public interface ITuple$gen $base {&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Gen-FxCop 1704    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;T{0} {0} {{ get; }}&amp;quot; -f $upperList[$count-1]&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;}&amp;quot;    &lt;br /&gt;} &lt;/p&gt;  &lt;p&gt;function script:Gen-TupleAccess   &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; param ( [int] $count = $(throw &amp;quot;Need a count&amp;quot;), [bool]$mutable )    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public int Count { get { return $count; } }&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public object this[int index] { get { switch (index){ &amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; 0..($count-1) | %{ &amp;quot;case $($_): return m_$($lowerList[$_]);&amp;quot; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;default: throw new InvalidOperationException(&amp;quot;&amp;quot;Bad Index&amp;quot;&amp;quot;);&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;} }&amp;quot; &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; if ( $mutable )   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;set { switch (index) {&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 0..($count-1) | %{ &amp;quot;case $($_): m_$($lowerList[$_]) = (T$($upperList[$_]))value; break;&amp;quot; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;default: throw new InvalidOperationException(&amp;quot;&amp;quot;Bad Index&amp;quot;&amp;quot;);&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;} } &amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;}&amp;quot;    &lt;br /&gt;} &lt;/p&gt;  &lt;p&gt;function script:Gen-OpEquals   &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; param ( [int] $count = $(throw &amp;quot;Need a count&amp;quot;), [string]$name )    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $OFS = ','    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $gen = &amp;quot;&amp;lt;&amp;quot; + [string](0..($count-1) | %{ &amp;quot;T&amp;quot;+$upperList[$_] }) + &amp;quot;&amp;gt;&amp;quot;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public static bool operator==($name$gen left, $name$gen right) {&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;return EqualityComparer&amp;lt;$name$gen&amp;gt;.Default.Equals(left,right); }&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public static bool operator!=($name$gen left, $name$gen right) {&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;return !EqualityComparer&amp;lt;$name$gen&amp;gt;.Default.Equals(left,right); }&amp;quot;    &lt;br /&gt;} &lt;/p&gt;  &lt;p&gt;function script:Gen-CompareTo   &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; param ( [int] $count = $(throw &amp;quot;Need a count&amp;quot;), [string]$name )    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $OFS = ','    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $gen = &amp;quot;&amp;lt;&amp;quot; + [string](0..($count-1) | %{ &amp;quot;T&amp;quot;+$upperList[$_] }) + &amp;quot;&amp;gt;&amp;quot;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public int CompareTo(object obj) {&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;return CompareTo(obj as $name$gen); }&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public int CompareTo($name$gen other) {&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;if ( Object.ReferenceEquals(other,null) ) { return 1; }&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;int code;&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; 0..($count-1) |     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; %{ &amp;quot;code = Comparer&amp;lt;T{0}&amp;gt;.Default.Compare(m_{1},other.m_{1}); if (code != 0) {{ return code; }}&amp;quot; -f $upperList[$_],$lowerList[$_] }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;return 0; }&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public static bool operator&amp;gt;($name$gen left, $name$gen right) { &amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;return Comparer&amp;lt;$name$gen&amp;gt;.Default.Compare(left,right) &amp;gt; 0; }&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public static bool operator&amp;lt;($name$gen left, $name$gen right) { &amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;return Comparer&amp;lt;$name$gen&amp;gt;.Default.Compare(left,right) &amp;lt; 0; }&amp;quot;    &lt;br /&gt;} &lt;/p&gt;  &lt;p&gt;function script:Get-Tuple   &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; param ( [int] $count, [bool]$mutable = $false )    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $OFS = ','    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $gen = &amp;quot;&amp;lt;&amp;quot; + [string](0..($count-1) | %{ &amp;quot;T&amp;quot;+$upperList[$_] }) + &amp;quot;&amp;gt;&amp;quot;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Gen-FxCop 1704    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Gen-Display $count    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if ( $count -gt 2 ) { Gen-FxCop 1005 }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $name = &amp;quot;{0}Tuple&amp;quot; -f (Get-Ternary $mutable &amp;quot;Mutable&amp;quot; &amp;quot;&amp;quot;)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public sealed class $name$gen : ITuple$gen,IEquatable&amp;lt;$name$gen&amp;gt;, IComparable&amp;lt;$name$gen&amp;gt;,IComparable {&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; (0..($count-1) | %{ Gen-Property $_ $mutable})    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Gen-Constructor $count $name    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Gen-TupleAccess $count $mutable    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Gen-Equals $count $name    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Gen-GetHashCode $count    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Gen-OpEquals $count $name    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Gen-CompareTo $count $name    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;}&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Gen-InferenceConstructor $count $name    &lt;br /&gt;} &lt;/p&gt;  &lt;p&gt;function Gen-TestTuple([int]$count, [string]$prefix)   &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $OFS = &amp;quot;,&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $v = [string](0..($count-1) | %{ $valueList[$_]} )    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;[TestMethod]&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public void {0}Access{1}() {{&amp;quot; -f $prefix,$count    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;var t = $prefix.Create($v);&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; for ( $i = 0; $i -lt $count; ++$i )    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;Assert.AreEqual({0},t.{1});&amp;quot; -f $valueList[$i],$upperList[$i];    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;}&amp;quot; &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;[TestMethod]&amp;quot;   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public void {0}GenericAccess{1}() {{&amp;quot; -f $prefix,$count    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;var t = $prefix.Create($v);&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; for ( $i = 0; $i -lt $count; ++$i )    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (&amp;quot;Assert.AreEqual({0},t[{1}]);&amp;quot; -f $valueList[$i],$i);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;Assert.AreEqual({0},t.Count);&amp;quot; -f $i     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;}&amp;quot; &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;[TestMethod]&amp;quot;   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public void {0}Equals{1}() {{&amp;quot; -f $prefix,$count    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;var t1 = $prefix.Create($v);&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;var t2 = $prefix.Create($v);&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;Assert.IsTrue(t1.Equals(t2));&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;}&amp;quot; &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;[TestMethod]&amp;quot;   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public void {0}NotEquals{1}() {{&amp;quot; -f $prefix,$count    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; for ( $i = 0; $i -lt $count; ++$i )    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $leftName = &amp;quot;t{0}_1&amp;quot; -f $i    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $rightName = &amp;quot;t{0}_2&amp;quot; -f $i    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $left = &amp;quot;var $leftName = $prefix.Create(&amp;quot; -f $i    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $right = &amp;quot;var $rightName = $prefix.Create(&amp;quot; -f $i    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; for ( $v = 0; $v -lt $count; ++$v )    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $left += &amp;quot;$v&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if ( $v -eq $i )    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $right += &amp;quot;-1&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $right += &amp;quot;$v&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if ( ($v + 1) -lt $count )   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $left += &amp;quot;,&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $right += &amp;quot;,&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;$left);&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;$right);&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;Assert.AreEqual($leftName.GetType(), $rightName.GetType());&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;quot;Assert.IsFalse($leftName.Equals($rightName));&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;}&amp;quot; &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;[TestMethod]&amp;quot;   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public void {0}CompareTest() {{ &amp;quot; -f $prefix    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;Assert.IsTrue($prefix.Create(1) &amp;lt; $prefix.Create(2));&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;Assert.IsTrue($prefix.Create(2) &amp;gt; $prefix.Create(1));&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;}&amp;quot;    &lt;br /&gt;} &lt;/p&gt;  &lt;p&gt;$output =    &lt;br /&gt;@&amp;quot;    &lt;br /&gt;using System;    &lt;br /&gt;using System.Collections.Generic;    &lt;br /&gt;using System.Diagnostics;    &lt;br /&gt;using System.Diagnostics.CodeAnalysis; &lt;/p&gt;  &lt;p&gt;namespace $namespace {    &lt;br /&gt;public interface ITuple {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; int Count { get; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; object this[int index] { get; }    &lt;br /&gt;}    &lt;br /&gt;&amp;quot;@    &lt;br /&gt;$OFS = [Environment]::NewLine    &lt;br /&gt;$output += [string](0..($tupleCount-1) | %{ Gen-ITuple ($_+1) })    &lt;br /&gt;$output += [string](0..($tupleCount-1) | %{ Get-Tuple ($_+1) })    &lt;br /&gt;$output += [string](0..($tupleCount-1) | %{ Get-Tuple ($_+1) $true })    &lt;br /&gt;$output += &amp;quot;}&amp;quot; &lt;/p&gt;  &lt;p&gt;$output &amp;gt; (join-path $scriptPath &amp;quot;Core\Tuple.cs&amp;quot;) &lt;/p&gt;  &lt;p&gt;$output =    &lt;br /&gt;@&amp;quot;    &lt;br /&gt;using System;    &lt;br /&gt;using System.Collections.Generic;    &lt;br /&gt;using Microsoft.VisualStudio.TestTools.UnitTesting;    &lt;br /&gt;using $namespace; &lt;/p&gt;  &lt;p&gt;namespace $($nameSpace)Test { &lt;/p&gt;  &lt;p&gt;[TestClass]   &lt;br /&gt;public class TupleTest{    &lt;br /&gt;&amp;quot;@    &lt;br /&gt;$output += Gen-TestTuple $tupleCount &amp;quot;Tuple&amp;quot;    &lt;br /&gt;$output += Gen-TestTuple $tupleCount &amp;quot;MutableTuple&amp;quot;    &lt;br /&gt;$output += &amp;quot;}}&amp;quot;    &lt;br /&gt;$output &amp;gt; (join-path $scriptPath &amp;quot;TestCore\TupleTest.cs&amp;quot;) &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7278167" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/PowerShell/default.aspx">PowerShell</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/FxCop/default.aspx">FxCop</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Generics/default.aspx">Generics</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Tuple/default.aspx">Tuple</category></item><item><title>Tuples Part 6: Comparing</title><link>http://blogs.msdn.com/jaredpar/archive/2008/01/22/tuples-part-6-comparing.aspx</link><pubDate>Tue, 22 Jan 2008 09:56:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7194139</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/7194139.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=7194139</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=7194139</wfw:comment><description>&lt;P&gt;&lt;A href="http://blogs.msdn.com/jaredpar/archive/2008/01/22/tuples-part-5-equality.aspx" mce_href="http://blogs.msdn.com/jaredpar/archive/2008/01/22/tuples-part-5-equality.aspx"&gt;Part 5&lt;/A&gt; produced equality tests for Tuples.&amp;nbsp; This section will add comparison support through the &lt;A href="http://msdn2.microsoft.com/en-us/library/4d7sx9hd.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/4d7sx9hd.aspx"&gt;IComparable&amp;lt;T&amp;gt;&lt;/A&gt; interface.&amp;nbsp; Implementing comparable is very similar to adding equality support.&amp;nbsp; Once again there is a generic class available to make all of the comparison decisions for us; &lt;A href="http://msdn2.microsoft.com/en-us/library/cfttsh47.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/cfttsh47.aspx"&gt;Comparer&amp;lt;T&amp;gt;&lt;/A&gt;.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The implementation will compare objects in a left to right fashion.&amp;nbsp; In this case the property corresponding to TA will be the left most, and TN the right most.&amp;nbsp; If all properties are equal (Compare returns 0) then the two items will be determined to be equal and will return 0.&lt;/P&gt;
&lt;P&gt;function script:Gen-CompareTo &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; param ( [int] $count = $(throw "Need a count") ) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $OFS = ',' &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $gen = "&amp;lt;" + [string](0..($count-1) | %{ "T"+$upperList[$_] }) + "&amp;gt;"&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "public int CompareTo(object other) {" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "return CompareTo(other as Tuple$gen); }" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "public int CompareTo(Tuple$gen other) {" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "if ( Object.ReferenceEquals(other,null) ) { return 1; }" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "int code;" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0..($count-1) | &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %{ "code = Comparer&amp;lt;T{0}&amp;gt;.Default.Compare(m_{1},other.m_{1}); if (code != 0) {{ return code; }}" -f $upperList[$_],$lowerList[$_] } &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "return 0; }" &lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;Once again the same questions arise about implementing IComparable&amp;lt;Tuple&amp;gt; vs IComparable&amp;lt;ITuple&amp;gt; (or both).&amp;nbsp; The arguments are fairly similar and as a result I decided to skip implementing the ITuple version for now.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7194139" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Generics/default.aspx">Generics</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Tuple/default.aspx">Tuple</category></item><item><title>Tuples Part 5: Equality</title><link>http://blogs.msdn.com/jaredpar/archive/2008/01/22/tuples-part-5-equality.aspx</link><pubDate>Tue, 22 Jan 2008 09:31:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7193911</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/7193911.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=7193911</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=7193911</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/jaredpar/archive/2008/01/10/tuples-part-4-interface.aspx"&gt;Part 4&lt;/a&gt; left us with a reusable, abstract and inference friendly Tuple class.&amp;#160; The next step is to be able to test for Tuple equality.&amp;#160; &lt;/p&gt;  &lt;p&gt;For the Tuple implementation, two tuples will be defined as equal if all of their members are equal.&amp;#160; Seems fairly straight forward.&amp;#160; The trick is in the implementation.&amp;#160; In addition to doing the typical override of Equals/GetHashCode the Tuple implementation will be implementing &lt;a href="http://msdn2.microsoft.com/en-us/library/ms131187.aspx"&gt;IEquatable&amp;lt;T&amp;gt;&lt;/a&gt; and overloading the standard equality operators.&lt;/p&gt;  &lt;p&gt;Tuple members are all unconstrained generic classes which leaves us with a non-great starting point.&amp;#160; &lt;/p&gt;  &lt;p&gt;For instance what if we are dealing with value types?&amp;#160; Is Equals() the best method to call?&amp;#160; What if the type in question implements &lt;a href="http://msdn2.microsoft.com/en-us/library/ms131187.aspx"&gt;IEquatable&amp;lt;T&amp;gt;&lt;/a&gt; or has a well known &lt;a href="http://msdn2.microsoft.com/en-us/library/ms132151.aspx"&gt;IEqualityComparer&amp;lt;T&amp;gt;&lt;/a&gt;?&amp;#160;&amp;#160; What if one or both of the arguments are reference types and null? What if they're value types and equal to null?&lt;/p&gt;  &lt;p&gt;Luckily there is an easy and straight forward solution.&amp;#160; The BCL defines a class, &lt;a href="http://msdn2.microsoft.com/en-us/library/ms132123.aspx"&gt;EqualityComparer&amp;lt;T&amp;gt;&lt;/a&gt;, which will properly perform equality comparisons for objects of a particular type.&amp;#160; This makes the Equals override very straight forward. &lt;/p&gt;  &lt;p&gt;There is one small trick to implementing Equals correctly.&amp;#160; The implementation explicitly uses Object.ReferenceEquals to check for null rather than ==.&amp;#160; The reason being is once operator== is defined for the type Tuple, comparison for even null will bind to this operator.&amp;#160; Part of checking for operator== will end up calling Equals and hence you can end in a stack overflow fairly quick.&amp;#160; Note that our implementation of == will work around this but it's still safer to be explicit.&amp;#160; &lt;/p&gt;  &lt;p&gt;function script:Gen-Equals   &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; param ( [int] $count = $(throw &amp;quot;Need a count&amp;quot;) )    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $OFS = ','    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $gen = &amp;quot;&amp;lt;&amp;quot; + [string](0..($count-1) | %{ &amp;quot;T&amp;quot;+$upperList[$_] }) + &amp;quot;&amp;gt;&amp;quot;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public override bool Equals(object obj) { &amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;return Equals(obj as Tuple$gen); }&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public bool Equals(Tuple$gen other) {&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;if ( Object.ReferenceEquals(other,null) ) { return false; }&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;if (&amp;quot;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $OFS = &amp;quot;&amp;amp;&amp;amp;&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [string](0..($count-1) | %{&amp;quot;EqualityComparer&amp;lt;T{0}&amp;gt;.Default.Equals(m_{1},other.m_{1})&amp;quot; -f $upperList[$_],$lowerList[$_] })    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;) { return true; }&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;return false;&amp;quot;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;}&amp;quot;    &lt;br /&gt;}&lt;/p&gt;  &lt;p&gt;GetHashCode can also utilize &lt;a href="http://msdn2.microsoft.com/en-us/library/ms132123.aspx"&gt;EqualityComparer&amp;lt;T&amp;gt;&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;function script:Gen-GetHashCode   &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; param ( [int] $count = $(throw &amp;quot;Need a count&amp;quot;) )    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public override int GetHashCode() {&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;int code = 0;&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; 0..($count-1) | %{ &amp;quot;code += EqualityComparer&amp;lt;T{0}&amp;gt;.Default.GetHashCode(m_{1});&amp;quot; -f $upperList[$_],$lowerList[$_] }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;return code;&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;}&amp;quot;    &lt;br /&gt;}&lt;/p&gt;  &lt;p&gt;Both of the operators are likewise straight forward.&amp;#160; As before mentioned &lt;a href="http://msdn2.microsoft.com/en-us/library/ms132123.aspx"&gt;EqualityComparer&amp;lt;T&amp;gt;&lt;/a&gt; will properly check for null and then perform an Equals call so it can be used as the standard operator code.&amp;#160; &lt;/p&gt;  &lt;p&gt;function script:Gen-OpEquals   &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; param ( [int] $count = $(throw &amp;quot;Need a count&amp;quot;) )    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $OFS = ','    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $gen = &amp;quot;&amp;lt;&amp;quot; + [string](0..($count-1) | %{ &amp;quot;T&amp;quot;+$upperList[$_] }) + &amp;quot;&amp;gt;&amp;quot;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public static bool operator==(Tuple$gen left, Tuple$gen right) {&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;return EqualityComparer&amp;lt;Tuple$gen&amp;gt;.Default.Equals(left,right); }&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;public static bool operator!=(Tuple$gen left, Tuple$gen right) {&amp;quot;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;quot;return !EqualityComparer&amp;lt;Tuple$gen&amp;gt;.Default.Equals(left,right); }&amp;quot;    &lt;br /&gt;}&lt;/p&gt;  &lt;p&gt;In addition to the methods, the Tuple class generation must be changed to implement IEquatable&amp;lt;Tuple&amp;lt;&amp;gt;&amp;gt;.&amp;#160; &lt;/p&gt;  &lt;p&gt;Some will notice that the implementation forces the equality comparison to be against a Tuple&amp;lt;T&amp;gt; vs an ITuple&amp;lt;T&amp;gt;.&amp;#160; There are a couple of reasons for this. &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;I have come up against specific scenarios where I wanted to compare Tuple&amp;lt;T&amp;gt; but not ITuple&amp;lt;T&amp;gt;.&amp;#160; This is not saying they don't exist (they do).&amp;#160; But I prefer to leave an implementation until I find a justification for implementing it.&amp;#160; &lt;/li&gt;    &lt;li&gt;By constraining to IEquatable&amp;lt;Tuple&amp;lt;T&amp;gt;&amp;gt; we are always comparing apples to apples.&amp;#160; If you try and perform an Equals against ITuple&amp;lt;TA&amp;gt; you're leaving yourself open to comparing apples and oranges.&amp;#160; Since ITuple&amp;lt;TA,TB&amp;gt; implements ITuple&amp;lt;TA&amp;gt; it is a valid target for the overload.&amp;#160; This type of equality seems scenario dependent and as such I left it out for the time.&amp;#160; Note with our current implementation it would be very easy to come back and add this later.&lt;/li&gt;    &lt;li&gt;To make #2 even stranger, once MutableTuples are implemented an implemantation of IEquatable&amp;lt;ITuple&amp;lt;TA&amp;gt;&amp;gt; might actually be comparing Tuple&amp;lt;TA,TB,TC&amp;gt; to MutableTuple&amp;lt;TA&amp;gt;.&amp;#160; &lt;/li&gt; &lt;/ol&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7193911" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Generics/default.aspx">Generics</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Tuple/default.aspx">Tuple</category></item><item><title>C# Lambda Type Inference</title><link>http://blogs.msdn.com/jaredpar/archive/2007/12/14/c-lambda-type-inference.aspx</link><pubDate>Fri, 14 Dec 2007 20:41:47 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6771356</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/6771356.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=6771356</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=6771356</wfw:comment><description>&lt;p&gt;One of the limitations of C# type inference is that you cannot use it to infer the type of a lambda expression.&amp;nbsp; For example, the following code will not compile&lt;/p&gt;&lt;pre class="code"&gt;            &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; f = () =&amp;gt; 4;
&lt;/pre&gt;
&lt;p&gt;Normally this is not too much of an issue because you can just explicitly declare the type of the lambda expression. &lt;/p&gt;&lt;pre class="code"&gt;            &lt;span style="color: rgb(43,145,175)"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt;&amp;gt; f = () =&amp;gt; 4;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;However, this can be annoying at times.&amp;nbsp; Once you start defining complex lambda expressions the Func/Action declaration can be quite convoluted.&amp;nbsp; Even worse, if your lambda returns an anonymous type, there is no way to declare a Func&amp;lt;&amp;gt; with the anonymous type parameter because you cannot describe it's shape.&amp;nbsp; &lt;/p&gt;&lt;pre class="code"&gt;            Func&amp;lt;???&amp;gt; f = () =&amp;gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; { Name = &lt;span style="color: rgb(163,21,21)"&gt;"foo"&lt;/span&gt; };&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;This is fixable though by using type inference.&amp;nbsp; The method is very similar to &lt;a href="http://blogs.msdn.com/jaredpar/archive/2007/10/01/casting-to-an-anonymous-type.aspx"&gt;other anonymous type type tricks&lt;/a&gt;.&amp;nbsp; While lambda type inference is not supported for variable declaration it is supported for parameters.&amp;nbsp; C# supports return type inference so that can be used to type the variable.&amp;nbsp; &lt;/p&gt;&lt;pre class="code"&gt;        &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Func&lt;/span&gt;&amp;lt;T&amp;gt; Lambda&amp;lt;T&amp;gt;(&lt;span style="color: rgb(43,145,175)"&gt;Func&lt;/span&gt;&amp;lt;T&amp;gt; del)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; del;
        }

        &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; Main(&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;[] args)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; f = Lambda(() =&amp;gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; { Name = &lt;span style="color: rgb(163,21,21)"&gt;"foo"&lt;/span&gt; });
        }&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6771356" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Generics/default.aspx">Generics</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Lambda/default.aspx">Lambda</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Type+Inference/default.aspx">Type Inference</category></item><item><title>Type Inference and IEnumerable</title><link>http://blogs.msdn.com/jaredpar/archive/2007/11/26/type-inference-and-ienumerable.aspx</link><pubDate>Tue, 27 Nov 2007 01:32:10 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6536165</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/6536165.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=6536165</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=6536165</wfw:comment><description>&lt;p&gt;This is somewhat of a follow up on a previous &lt;a href="http://blogs.msdn.com/jaredpar/archive/2007/10/04/ienumerable-and-ienumerable-of-t.aspx"&gt;post&lt;/a&gt; I did on the difference between &lt;a href="http://msdn2.microsoft.com/en-us/library/9eekhta0.aspx"&gt;IEnumerable(Of T)&lt;/a&gt; and the &lt;a href="http://msdn2.microsoft.com/en-us/library/9eekhta0.aspx"&gt;IEnumerable&lt;/a&gt; interfaces.&amp;nbsp; &lt;/p&gt; &lt;p&gt;I've seen several people type in the following code and wonder if there was a fundamental bug in the type inference code.&lt;/p&gt;&lt;pre class="code"&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Sub&lt;/span&gt; Form1_Load(&lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; sender &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; System.Object, &lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; e &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; System.EventArgs) &lt;span style="color: rgb(0,0,255)"&gt;Handles&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;MyBase&lt;/span&gt;.Load
        &lt;span style="color: rgb(0,0,255)"&gt;For&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Each&lt;/span&gt; cur &lt;span style="color: rgb(0,0,255)"&gt;In&lt;/span&gt; Controls
            cur.Text = &lt;span style="color: rgb(163,21,21)"&gt;"A Value"
&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;Next
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Sub&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;This code will produce an error stating that "Text" is not a member of object.&amp;nbsp; Users expected type inference to type the variable "cur" as Control.&amp;nbsp; Unfortunately this is "By Design".&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Much of the original .Net Framework was written before the CLR implemented support for generics.&amp;nbsp; As a result all of the collection classes were loosely typed to Object by implementing &lt;a href="http://msdn2.microsoft.com/en-us/library/9eekhta0.aspx"&gt;IEnumerable&lt;/a&gt;.&amp;nbsp; So in this case type inference will correctly type this as Object.&lt;/p&gt;
&lt;p&gt;There are 2 ways to fix this problem. &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Explicitly type the For Each variable to be the actual type of objects in the collection&lt;/li&gt;
&lt;li&gt;Use a Shim to change the type of the collection. (see &lt;a title="http://blogs.msdn.com/jaredpar/archive/2007/10/04/ienumerable-and-ienumerable-of-t.aspx" href="http://blogs.msdn.com/jaredpar/archive/2007/10/04/ienumerable-and-ienumerable-of-t.aspx"&gt;http://blogs.msdn.com/jaredpar/archive/2007/10/04/ienumerable-and-ienumerable-of-t.aspx&lt;/a&gt;)&lt;/li&gt;&lt;/ol&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6536165" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Orcas/default.aspx">Orcas</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Generics/default.aspx">Generics</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Type+Inference/default.aspx">Type Inference</category></item><item><title>Names of Anonymous Type Members</title><link>http://blogs.msdn.com/jaredpar/archive/2007/11/09/names-of-anonymous-type-members.aspx</link><pubDate>Sat, 10 Nov 2007 03:46:40 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6034007</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/6034007.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=6034007</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=6034007</wfw:comment><description>&lt;p&gt;Recently I was asked how can you get a list of anonymous type member names given a query of anonymous types.&amp;nbsp; The quick answer is that you can use a quick bit of reflection to get back the names.&amp;nbsp; &lt;/p&gt;&lt;pre class="code"&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function&lt;/span&gt; GetAnonymousTypeMemberNames(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; T)(&lt;span style="color: rgb(0,0,255)"&gt;ByVal&lt;/span&gt; anonymousType &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; T) &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; List(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;String&lt;/span&gt;)
        &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; type = &lt;span style="color: rgb(0,0,255)"&gt;GetType&lt;/span&gt;(T)
        &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; list = &lt;span style="color: rgb(0,0,255)"&gt;New&lt;/span&gt; List(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;String&lt;/span&gt;)
        &lt;span style="color: rgb(0,0,255)"&gt;For&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Each&lt;/span&gt; cur &lt;span style="color: rgb(0,0,255)"&gt;In&lt;/span&gt; type.GetProperties(Reflection.BindingFlags.Public &lt;span style="color: rgb(0,0,255)"&gt;Or&lt;/span&gt; Reflection.BindingFlags.Instance)
            list.Add(cur.Name)
        &lt;span style="color: rgb(0,0,255)"&gt;Next
&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;Return&lt;/span&gt; list
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;The longer question is how can you get back a list of anonymous type member names given a query result?&amp;nbsp; As long as you know the query will be populated you can just use the first member to get your result.&lt;/p&gt;&lt;pre class="code"&gt;        &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; q = &lt;span style="color: rgb(0,0,255)"&gt;From&lt;/span&gt; it &lt;span style="color: rgb(0,0,255)"&gt;In&lt;/span&gt; &lt;span style="color: rgb(163,21,21)"&gt;"astring"&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Select&lt;/span&gt; a = it, b = it &amp;amp; &lt;span style="color: rgb(163,21,21)"&gt;"b"
&lt;/span&gt;        GetAnonymousTypeMemberNames(q.First())&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;However you can't guarantee that a query will always have data in it.&amp;nbsp; Another route is to consider the contract of the From ... Select statement.&amp;nbsp; This will produce a query which implements &lt;a href="http://msdn2.microsoft.com/en-us/library/9eekhta0.aspx"&gt;IEnumerable(Of T).&lt;/a&gt;&amp;nbsp; For a query T will be the anonymous type that is generated[1].&amp;nbsp; We can query the metadata of the returned type to get the System.Type for the anonymous type regardless of the type actually implementing &lt;a href="http://msdn2.microsoft.com/en-us/library/9eekhta0.aspx"&gt;IEnumerable(Of T).&lt;/a&gt;&amp;nbsp; &lt;/p&gt;&lt;pre class="code"&gt;        &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; q = &lt;span style="color: rgb(0,0,255)"&gt;From&lt;/span&gt; it &lt;span style="color: rgb(0,0,255)"&gt;In&lt;/span&gt; &lt;span style="color: rgb(163,21,21)"&gt;"astring"&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Select&lt;/span&gt; a = it, b = it &amp;amp; &lt;span style="color: rgb(163,21,21)"&gt;"b"
&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; enumerableInterface = &lt;span style="color: rgb(0,0,255)"&gt;GetType&lt;/span&gt;(IEnumerable(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; ))
        &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; enumerableType = q.GetType().GetInterface(enumerableInterface.FullName)
        &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; anonymousTypeType = enumerableType.GetGenericArguments(0)&lt;/pre&gt;
&lt;p&gt;[1] This is assuming that you didn't write a query which returns a field directly and avoids creating the anonymous type.&amp;nbsp; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6034007" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Anonymous+Types/default.aspx">Anonymous Types</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Generics/default.aspx">Generics</category></item><item><title>IEnumerable and IEnumerable(Of T) 2</title><link>http://blogs.msdn.com/jaredpar/archive/2007/10/05/ienumerable-and-ienumerable-of-t-2.aspx</link><pubDate>Fri, 05 Oct 2007 18:43:06 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5294892</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/5294892.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=5294892</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=5294892</wfw:comment><description>&lt;p&gt;Quick follow up to my earlier &lt;a href="http://blogs.msdn.com/jaredpar/archive/2007/10/04/ienumerable-and-ienumerable-of-t.aspx"&gt;post&lt;/a&gt;.&amp;nbsp; Fixing this issue in C# is even easier because of the existence of iterators.&amp;nbsp; &lt;/p&gt;&lt;pre class="code"&gt;        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;object&lt;/span&gt;&amp;gt; Shim(System.Collections.&lt;span style="color: rgb(43,145,175)"&gt;IEnumerable&lt;/span&gt; enumerable)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;foreach&lt;/span&gt; (&lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; cur &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; enumerable)
            {
                &lt;span style="color: rgb(0,0,255)"&gt;yield&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; cur;
            }
        }
&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5294892" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/DotNet/default.aspx">DotNet</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Generics/default.aspx">Generics</category></item><item><title>IEnumerable and IEnumerable(Of T)</title><link>http://blogs.msdn.com/jaredpar/archive/2007/10/04/ienumerable-and-ienumerable-of-t.aspx</link><pubDate>Thu, 04 Oct 2007 21:29:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5276832</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/5276832.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=5276832</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=5276832</wfw:comment><description>&lt;p&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/9eekhta0.aspx"&gt;IEnumerable(Of T)&lt;/a&gt; is a huge step up in the 2.0 framework from the original &lt;a href="http://msdn2.microsoft.com/en-us/library/9eekhta0.aspx"&gt;IEnumerable&lt;/a&gt; interface.&amp;nbsp; It provides a typed enumeration which eliminates lots of nasty casts.&amp;nbsp; The best part is that IEnumerable(Of T) is backwards compatible with IEnumerable (it inherits from it).&amp;nbsp; &lt;/p&gt; &lt;p&gt;What's frustrating is that IEnumerable is not forwards compatible with IEnumerable(Of Object).&amp;nbsp; This prevents you from using IEnumerable anywhere IEnumerable(Of Object) or an inferred IEnumerable&amp;lt;T&amp;gt; is expected even though they have almost the same interface. The framework couldn't take the same approach and have IEnumerable inherit IEnumerable(Of Object) because it would have broken any implementer on upgrade to the 2.0 framework.&amp;nbsp; &lt;/p&gt; &lt;p&gt;The good news is this is easy to shim.&amp;nbsp; Since IEnumerable(Of Object) and IEnumerable have virtually the same, it's easy to create a wrapper class that forwards the calls into the base enumerator.&lt;/p&gt; &lt;p&gt;The basic shim involves two classes&amp;nbsp; &lt;/p&gt; &lt;ul&gt; &lt;li&gt;EnumerableShim - Implements IEnumerable(Of Object).&amp;nbsp; This class wraps an IEnumerable object only has two methods.&amp;nbsp; &lt;/li&gt;&lt;/ul&gt;&lt;pre class="code"&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function&lt;/span&gt; GetEnumerator() &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; System.Collections.Generic.IEnumerator(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Object&lt;/span&gt;) &lt;span style="color: rgb(0,0,255)"&gt;Implements&lt;/span&gt; System.Collections.Generic.IEnumerable(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Object&lt;/span&gt;).GetEnumerator
        &lt;span style="color: rgb(0,0,255)"&gt;Return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;New&lt;/span&gt; EnumeratorShim(m_enumerable.GetEnumerator())
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function

&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function&lt;/span&gt; GetEnumerator1() &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; System.Collections.IEnumerator &lt;span style="color: rgb(0,0,255)"&gt;Implements&lt;/span&gt; System.Collections.IEnumerable.GetEnumerator
        &lt;span style="color: rgb(0,0,255)"&gt;Return&lt;/span&gt; m_enumerable.GetEnumerator()
    &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;EnumeratorShim - Implements IEnumerator(Of Object).&amp;nbsp; This class wraps the IEnumerator object created above and implements the standard methods by forwarding all calls to the IEnumerator implementation.&amp;nbsp; For example ...&lt;/li&gt;&lt;/ul&gt;&lt;pre class="code"&gt;        &lt;span style="color: rgb(0,0,255)"&gt;Public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;ReadOnly&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Property&lt;/span&gt; Current() &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Object&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Implements&lt;/span&gt; System.Collections.Generic.IEnumerator(&lt;span style="color: rgb(0,0,255)"&gt;Of&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Object&lt;/span&gt;).Current
            &lt;span style="color: rgb(0,0,255)"&gt;Get
&lt;/span&gt;                &lt;span style="color: rgb(0,0,255)"&gt;Return&lt;/span&gt; m_impl.Current
            &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Get
&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;End&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Property
&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Now whenever your stuck with and old framework collection that was not updated for generic support, you can use it in generic situations with a single indirection call.&amp;nbsp; &lt;/p&gt;&lt;pre class="code"&gt;        &lt;span style="color: rgb(0,0,255)"&gt;Dim&lt;/span&gt; list &lt;span style="color: rgb(0,0,255)"&gt;As&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;New&lt;/span&gt; ArrayList
        ...
        SomeMethod(&lt;span style="color: rgb(0,0,255)"&gt;New&lt;/span&gt; EnumerableShim(list))&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5276832" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Generics/default.aspx">Generics</category></item><item><title>Casting to an Anonymous Type</title><link>http://blogs.msdn.com/jaredpar/archive/2007/10/01/casting-to-an-anonymous-type.aspx</link><pubDate>Mon, 01 Oct 2007 18:15:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5224427</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/5224427.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=5224427</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=5224427</wfw:comment><description>&lt;P&gt;This discussion is building upon a previous post on how to acquire an &lt;A href="http://blogs.msdn.com/jaredpar/archive/2007/08/01/coding-quiz-anonymous-type-types.aspx" mce_href="http://blogs.msdn.com/jaredpar/archive/2007/08/01/coding-quiz-anonymous-type-types.aspx"&gt;anonymous type ... type&lt;/A&gt;.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The next question is, how can you cast an arbitrary object into an anonymous type?&amp;nbsp; At a glance this doesn't seem possible as you cannot directly express the type of an anonymous type in code.&amp;nbsp; For instance the following code is not legal.&amp;nbsp; &lt;/P&gt;&lt;PRE class=code&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;Dim&lt;/SPAN&gt; o &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;Object&lt;/SPAN&gt; = SomeCall() 
&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;Dim&lt;/SPAN&gt; x = &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;Directcast&lt;/SPAN&gt;(o, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;New&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;With&lt;/SPAN&gt; {.a = 5})&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Even though it's not possible to directly express the type in code, we can indirectly express it via type inference.&amp;nbsp; Anonymous Types are strongly typed in the compiler and it is possible to infer these types where inference is available.&amp;nbsp; &lt;/P&gt;&lt;PRE class=code&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;Public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;Function&lt;/SPAN&gt; CastSpecial(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;Of&lt;/SPAN&gt; T)(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;ByVal&lt;/SPAN&gt; o &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;Object&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;ByVal&lt;/SPAN&gt; t &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;As&lt;/SPAN&gt; T) &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;As&lt;/SPAN&gt; T 
&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;    Return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;DirectCast&lt;/SPAN&gt;(o, T)
&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; End&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;Function &lt;/SPAN&gt;&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;The above function allows us to perform a DirectCast as long as we have an instance of the type we want to cast to.&amp;nbsp; Now we can call the code and passing in the appropriate anonymous type instance.&lt;/P&gt;&lt;PRE class=code&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;Dim&lt;/SPAN&gt; o &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;As&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;Object&lt;/SPAN&gt; = SomeCall()
&lt;SPAN style="COLOR: rgb(0,0,255)"&gt; Dim&lt;/SPAN&gt; x = CastSpecial(o, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;New&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;With&lt;/SPAN&gt; {.a = 5})&lt;/PRE&gt;
&lt;P&gt;There are a couple of caveats to this approach though.&amp;nbsp; &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;The actual anonymous type and the one you are casting to must be exactly the same.&amp;nbsp; No polymorphism can be involved.&lt;/LI&gt;
&lt;LI&gt;The anonymous type must be created in the same assembly where you are performing the cast.&amp;nbsp; Anonymous types are specific to the assembly they are created in so performing the cast accross assemblies will cause a InvalidCastException to occur.&lt;/LI&gt;
&lt;LI&gt;It does needlessly create an object to perform the cast.&lt;/LI&gt;&lt;/OL&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5224427" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Anonymous+Types/default.aspx">Anonymous Types</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Generics/default.aspx">Generics</category></item><item><title>Singleton Pattern</title><link>http://blogs.msdn.com/jaredpar/archive/2007/09/04/singleton-pattern.aspx</link><pubDate>Tue, 04 Sep 2007 20:58:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4744922</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/4744922.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=4744922</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=4744922</wfw:comment><description>&lt;P&gt;Quite awhile back I posted about how to create a re-usable singleton pattern in .Net.&amp;nbsp; Link is &lt;A href="http://blogs.msdn.com/jaredpar/archive/2004/11/24/269133.aspx" mce_href="http://blogs.msdn.com/jaredpar/archive/2004/11/24/269133.aspx"&gt;here&lt;/A&gt;.&amp;nbsp; A bit of time has passed and I've altered the pattern a bit.&amp;nbsp; The reasons for the change are some new type inference patterns and FxCop cleanliness.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The first pattern I introduced had a couple of FxCop violations.&amp;nbsp; Namely Microsoft.Design CA1000 - Do not declare static members on generic types.&amp;nbsp; The logic here being that static methods don't have any type inference benefits as you must explicitly add the type into the name of the type you were using (in this case Singleton).&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Secondly because T was at a class level rather than a method level I couldn't have granualar methods which had differing set of constraints.&amp;nbsp; The result was a pattern that was not always easy to write out.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The new pattern takes care of both of these problems.&amp;nbsp; It has two methods.&amp;nbsp; One of which can be satisfied with a trivial lambda expression.&amp;nbsp; The other can easily be used for classes that satisfy the generic constraint new() with no additional lambda.&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;c1
&lt;/SPAN&gt;    {
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;c1&lt;/SPAN&gt; Instance1 
        {
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;get&lt;/SPAN&gt; { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Singleton&lt;/SPAN&gt;.GetInstance(() =&amp;gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;c1&lt;/SPAN&gt;());}
        }

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;c1&lt;/SPAN&gt; Instance2
        {
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;get&lt;/SPAN&gt; { &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Singleton&lt;/SPAN&gt;.GetInstance&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;c1&lt;/SPAN&gt;&amp;gt;(); }
        }

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; c1()
        {

        }
        
    }&lt;/PRE&gt;
&lt;P&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;Below is the new singleton pattern.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;    public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;delegate&lt;/SPAN&gt; T &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Operation&lt;/SPAN&gt;&amp;lt;T&amp;gt;();&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;PRE class=code&gt;    &lt;SPAN style="COLOR: rgb(128,128,128)"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,128,0)"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(128,128,128)"&gt;&amp;lt;summary&amp;gt;
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: rgb(128,128,128)"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,128,0)"&gt; Used for classes that are single instances per appdomain
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: rgb(128,128,128)"&gt;///&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,128,0)"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(128,128,128)"&gt;&amp;lt;/summary&amp;gt;
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Singleton
&lt;/SPAN&gt;    {
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Storage&lt;/SPAN&gt;&amp;lt;T&amp;gt;
        {
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;internal&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt; T s_instance;
        }

        [&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;SuppressMessage&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"Microsoft.Reliability"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"CA2002"&lt;/SPAN&gt;)]
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt; T GetInstance&amp;lt;T&amp;gt;(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Operation&lt;/SPAN&gt;&amp;lt;T&amp;gt; op)
        {
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Storage&lt;/SPAN&gt;&amp;lt;T&amp;gt;.s_instance == &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;null&lt;/SPAN&gt;)
            {
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;lock&lt;/SPAN&gt; (&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Storage&lt;/SPAN&gt;&amp;lt;T&amp;gt;))
                {
                    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Storage&lt;/SPAN&gt;&amp;lt;T&amp;gt;.s_instance == &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;null&lt;/SPAN&gt;)
                    {
                        T temp = op();
                        System.Threading.&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Thread&lt;/SPAN&gt;.MemoryBarrier();
                        &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Storage&lt;/SPAN&gt;&amp;lt;T&amp;gt;.s_instance = temp;
                    }
                }
            }
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Storage&lt;/SPAN&gt;&amp;lt;T&amp;gt;.s_instance;
        }

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt; T GetInstance&amp;lt;T&amp;gt;()
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;where&lt;/SPAN&gt; T : &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt;()
        {
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; GetInstance(() =&amp;gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; T());
        }
    }

&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;    #endregion
&lt;/SPAN&gt;}
&lt;/PRE&gt;
&lt;P&gt;Edit: Originally forgot to add the signature for Operation&amp;lt;T&amp;gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4744922" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/VB/default.aspx">VB</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Orcas/default.aspx">Orcas</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/Generics/default.aspx">Generics</category></item></channel></rss>