<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Jon Skeet: Coding Blog : Evil Code</title><link>http://msmvps.com/blogs/jon_skeet/archive/tags/Evil+Code/default.aspx</link><description>Tags: Evil Code</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>API design: choosing between non-ideal options</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/09/14/api-design-choosing-between-non-ideal-options.aspx</link><pubDate>Mon, 14 Sep 2009 16:38:05 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1723277</guid><dc:creator>skeet</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1723277</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1723277</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/09/14/api-design-choosing-between-non-ideal-options.aspx#comments</comments><description>&lt;p&gt;So, &lt;a href="http://code.google.com/p/unconstrained-melody"&gt;UnconstrainedMelody&lt;/a&gt; is coming on quite nicely. It now has quite a few useful options for flags enums, &amp;quot;normal enums&amp;quot; and delegates. However, there are two conflicting limitations which leave a couple of options. (Other related answers on Stack Overflow have suggested alternative approaches, basically.)&lt;/p&gt;  &lt;p&gt;Currently, most of the enums code is in two classes: Flags and Enums. Both are non-generic: the methods within them are generic methods, so they have type parameters (and constraints). The main benefit of this is that generic type inference only applies to generic methods, and I &lt;em&gt;definitely&lt;/em&gt; want that for extension methods and anywhere else it makes sense.&lt;/p&gt;  &lt;p&gt;The drawback is that properties can&amp;#39;t be generic. That means my API is entirely expressed in terms of methods, which can be a pain. The option to work around this is to have a generic type which properties in. This adds confusion and guesswork - what call is where?&lt;/p&gt;  &lt;p&gt;To recap, the options are:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="InlineComment"&gt;// Option 1 (current): all methods in a nongeneric class:&lt;/span&gt;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// Some calls which are logically properties end up&lt;/span&gt;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// as methods...&lt;/span&gt;    &lt;br /&gt;IList&amp;lt;Foo&amp;gt; foos = Enums.GetValues&amp;lt;Foo&amp;gt;();    &lt;br /&gt;&lt;span class="InlineComment"&gt;// Type infererence for extenion methods&lt;/span&gt;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// Note that we couldn&amp;#39;t have a Description property&lt;/span&gt;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// as we don&amp;#39;t have extension properties&lt;/span&gt;    &lt;br /&gt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; firstDescription = foos[0].GetDescription();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&lt;span class="InlineComment"&gt;// Option 2: Use just a generic type:&lt;/span&gt;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// Now we can use a property...&lt;/span&gt;    &lt;br /&gt;IList&amp;lt;Foo&amp;gt; foos = Enums&amp;lt;Foo&amp;gt;.Values;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// But we can&amp;#39;t use type inference&lt;/span&gt;    &lt;br /&gt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; firstDescription = Enums&amp;lt;Foo&amp;gt;.GetDescription(foos[0]);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&lt;span class="InlineComment"&gt;// Option 3: Use a mixture (Enums and Enums&amp;lt;T&amp;gt;):&lt;/span&gt;    &lt;br /&gt;IList&amp;lt;Foo&amp;gt; foos = Enums&amp;lt;Foo&amp;gt;.Values;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// All looks good...&lt;/span&gt;    &lt;br /&gt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; firstDescription = foos[0].GetDescription();    &lt;br /&gt;&lt;span class="InlineComment"&gt;// ... but the user has to know when to use which class&lt;/span&gt; &lt;/div&gt;  &lt;p&gt;All of these are somewhat annoying. If we &lt;em&gt;only &lt;/em&gt;put extension methods into the nongeneric class, then I guess users would never need to really think about that - they&amp;#39;d pretty much always be calling the methods via the extension method syntactic sugar anyway. It still feels like a pretty arbitrary split though.&lt;/p&gt;  &lt;p&gt;Any thoughts? Which is more important - conceptual complexity, or the idiomatic client code you end up with once that complexity has been mastered? Is it reasonable to make design decisions like this around what is essentially a single piece of syntactic sugar (extension methods)?&lt;/p&gt;  &lt;p&gt;(By the way, if anyone ever wanted justification for extension properties, I think this is a good example... Description feels like it really &lt;em&gt;should&lt;/em&gt; be a property.)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1723277" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Evil+Code/default.aspx">Evil Code</category></item><item><title>Evil Code of the Day: variance and overloading</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/07/13/evil-code-of-the-day-variance-and-overloading.aspx</link><pubDate>Mon, 13 Jul 2009 16:10:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1700112</guid><dc:creator>skeet</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1700112</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1700112</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/07/13/evil-code-of-the-day-variance-and-overloading.aspx#comments</comments><description>&lt;p&gt;(Note that this kind of breakage was &lt;a href="http://blogs.msdn.com/ericlippert/archive/2007/11/02/covariance-and-contravariance-in-c-part-nine-breaking-changes.aspx"&gt;mentioned a long time ago in Eric Lippert&amp;#39;s blog&lt;/a&gt;, although not in this exact form.)&lt;/p&gt;
&lt;p&gt;Whenever a conversion becomes available where it wasn&amp;#39;t before, overload resolution can change its behaviour. From C# 1 to C# 2 this happened due to delegate variance with method group conversions - now the same thing is true for generic variance for interfaces.&lt;/p&gt;
&lt;p&gt;What does the following code print?&lt;/p&gt;
&lt;div class="code"&gt; &lt;span class="Namespace"&gt;using&lt;/span&gt;&amp;nbsp;System;&lt;br /&gt; &lt;span class="Namespace"&gt;using&lt;/span&gt;&amp;nbsp;System.Collections.Generic;&lt;br /&gt; &lt;br /&gt; &lt;span class="ReferenceType"&gt;class&lt;/span&gt;&amp;nbsp;Base&lt;br /&gt; {&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt;&amp;nbsp;Foo(IEnumerable&amp;lt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt;&amp;gt;&amp;nbsp;strings)&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span class="String"&gt;&amp;quot;Strings&amp;quot;&lt;/span&gt;);&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; &lt;span class="ReferenceType"&gt;class&lt;/span&gt;&amp;nbsp;Derived&amp;nbsp;:&amp;nbsp;Base&lt;br /&gt; {&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt;&amp;nbsp;Foo(IEnumerable&amp;lt;&lt;span class="ReferenceType"&gt;object&lt;/span&gt;&amp;gt;&amp;nbsp;objects)&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;span class="String"&gt;&amp;quot;Objects&amp;quot;&lt;/span&gt;);&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; &lt;span class="ReferenceType"&gt;class&lt;/span&gt;&amp;nbsp;Test&lt;br /&gt; {&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span class="ValueType"&gt;void&lt;/span&gt;&amp;nbsp;Main()&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;List&amp;lt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt;&amp;gt;&amp;nbsp;strings&amp;nbsp;=&amp;nbsp;&lt;span class="Keyword"&gt;new&lt;/span&gt;&amp;nbsp;List&amp;lt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt;&amp;gt;();&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="Keyword"&gt;new&lt;/span&gt;&amp;nbsp;Derived().Foo(strings);&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt; } &lt;/div&gt;
&lt;p&gt;The correct answer is &amp;quot;it depends on which version of C# &lt;em&gt;and&lt;/em&gt; .NET framework you&amp;#39;re using.&amp;quot;&lt;/p&gt;
&lt;p&gt;If you&amp;#39;re using C# 4.0 and .NET 4.0, then IEnumerable&amp;lt;T&amp;gt; is covariant: there&amp;#39;s an implicit conversion from IEnumerable&amp;lt;string&amp;gt; to IEnumerable&amp;lt;object&amp;gt;, so the derived overload is used.&lt;/p&gt;
&lt;p&gt;If you&amp;#39;re using C# 4.0 but .NET 3.5 or earlier then the compiler still knows about variance in general, but the interface in the framework doesn&amp;#39;t have the appropriate metadata to indicate it, so there&amp;#39;s no conversion available, and the base class overload is used.&lt;/p&gt;
&lt;p&gt;If you&amp;#39;re using C# 3.0 or earlier then the compiler doesn&amp;#39;t know about generic variance at all, so again the base class overload is used.&lt;/p&gt;
&lt;p&gt;So, this is a breaking change, and a fairly subtle one at that - and unlike the method group conversion in .NET 2.0, the compiler in .NET 4.0 beta 1 doesn&amp;#39;t issue a warning about it. I&amp;#39;ll edit this post when there&amp;#39;s an appropriate Connect ticket about it...&lt;/p&gt;
&lt;p&gt;In general though, I&amp;#39;d say it&amp;#39;s worth avoiding overloading a method declared in a base class unless you really have to. In particular, overloading it using the same number of parameters but more general ones seems to be a recipe for unreadable code.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1700112" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_+4/default.aspx">C# 4</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Evil+Code/default.aspx">Evil Code</category></item></channel></rss>