<?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>Simulated Covariance for .NET Generics</title><link>http://blogs.msdn.com/kcwalina/archive/2008/04/02/SimulatedCovariance.aspx</link><description>I just wrote this pattern, but I am not sure if I should add it officially to the Framework Design Guidelines. It seems like a bit of a corner case scenario, though I do get questions about it from time to time. Anyway, let me know what you think. Different</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>re: Simulated Covariance for .NET Generics</title><link>http://blogs.msdn.com/kcwalina/archive/2008/04/02/SimulatedCovariance.aspx#8351955</link><pubDate>Wed, 02 Apr 2008 20:36:34 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8351955</guid><dc:creator>Bill Sorensen</dc:creator><description>&lt;p&gt;Interesting, thanks!&lt;/p&gt;
&lt;p&gt;One typo:&lt;/p&gt;
&lt;p&gt;// this of course does not complie&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ^^^^^&lt;/p&gt;
&lt;p&gt;Also, the article says that&lt;/p&gt;
&lt;p&gt;&amp;quot;in case of IEnumerable&amp;lt;object&amp;gt;, the object appears only in the output position&amp;quot;&lt;/p&gt;
&lt;p&gt;and then&lt;/p&gt;
&lt;p&gt;&amp;quot;in IEnumerable&amp;lt;T&amp;gt;, the T is at covariant positions (inputs). In List&amp;lt;T&amp;gt;, the T is at covariant and contravariant (output) positions.&amp;quot;&lt;/p&gt;
&lt;p&gt;It appears as though inputs and outputs were reversed.&lt;/p&gt;</description></item><item><title>re: Simulated Covariance for .NET Generics</title><link>http://blogs.msdn.com/kcwalina/archive/2008/04/02/SimulatedCovariance.aspx#8352133</link><pubDate>Wed, 02 Apr 2008 21:53:56 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8352133</guid><dc:creator>Abraham Pinzur</dc:creator><description>&lt;p&gt;I have encountered this situation in the past, and look forward to having your perspective to inform my design in the future. Thanks for sharing!&lt;/p&gt;</description></item><item><title>re: Simulated Covariance for .NET Generics</title><link>http://blogs.msdn.com/kcwalina/archive/2008/04/02/SimulatedCovariance.aspx#8352173</link><pubDate>Wed, 02 Apr 2008 22:22:52 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8352173</guid><dc:creator>Jonathan Pryor</dc:creator><description>&lt;p&gt;It's a good idea to document this pattern in the FxDG, as I independently reinvented this pattern (poorly) while helping someone on IRC recently...&lt;/p&gt;
&lt;p&gt;What should also be mentioned, perhaps in a sidebar, are ways to avoid this. &amp;nbsp;In particular, the C# Annotated Standard section 25.7 has a &amp;quot;Using constraints to simulate Java wildcard types&amp;quot; sidebar, ways to (ab)use the C# constraint mechanism to support collections of types rooted at some base type.&lt;/p&gt;
&lt;p&gt;Thus, if PrintItems() can be made generic, it can be written as:&lt;/p&gt;
&lt;p&gt; &amp;nbsp;static void PrintItems&amp;lt;T&amp;gt; (IEnumerable&amp;lt;T&amp;gt; anyList)&lt;/p&gt;
&lt;p&gt; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;foreach (object obj in anyList)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;Console.WriteLine (obj.ToString ());&lt;/p&gt;
&lt;p&gt; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;This suffers in that we must use generic methods to do this (compare to your original example where PrintItems() wasn't generic), but this is something that should be more widely known, and documenting it in the FxDG would be useful.&lt;/p&gt;
&lt;p&gt;See also: &lt;a rel="nofollow" target="_new" href="http://www.jprl.com/Blog/archive/development/2007/Aug-31.html#jcs-csharp-wildcards"&gt;http://www.jprl.com/Blog/archive/development/2007/Aug-31.html#jcs-csharp-wildcards&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; - Jon&lt;/p&gt;</description></item><item><title>re: Simulated Covariance for .NET Generics</title><link>http://blogs.msdn.com/kcwalina/archive/2008/04/02/SimulatedCovariance.aspx#8352382</link><pubDate>Wed, 02 Apr 2008 23:59:54 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8352382</guid><dc:creator>kcwalina</dc:creator><description>&lt;p&gt;Bill, thanks for pointing out the errors. I updated the text.&lt;/p&gt;
</description></item><item><title>re: Simulated Covariance for .NET Generics</title><link>http://blogs.msdn.com/kcwalina/archive/2008/04/02/SimulatedCovariance.aspx#8352405</link><pubDate>Thu, 03 Apr 2008 00:15:03 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8352405</guid><dc:creator>kcwalina</dc:creator><description>&lt;p&gt;Jon, great point! I should have included it in the guideline. &lt;/p&gt;
&lt;p&gt;But, in addition of some perf overhead related to JITing separate methods for each T, you cannot use the trick for properties, ... and databinging APIs (properties) actually do need a single root.&lt;/p&gt;
</description></item><item><title>re: Simulated Covariance for .NET Generics</title><link>http://blogs.msdn.com/kcwalina/archive/2008/04/02/SimulatedCovariance.aspx#8352927</link><pubDate>Thu, 03 Apr 2008 05:45:31 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8352927</guid><dc:creator>qrli</dc:creator><description>&lt;p&gt;It looks good. However, the .NET guideline doc is getting longer and longer. If it is too long and takes too much time for everyone to understand, it will not be so practical. I like the way C# enforce many usage by the language itself, instead of having to remember tons of patterns do the basic things right like in Java. My wish is that you great guys can solve that in the compiler one day. But for now, the pattern is a good walkaround.&lt;/p&gt;</description></item><item><title>re: Simulated Covariance for .NET Generics</title><link>http://blogs.msdn.com/kcwalina/archive/2008/04/02/SimulatedCovariance.aspx#8353182</link><pubDate>Thu, 03 Apr 2008 09:43:50 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8353182</guid><dc:creator>Larry Lard</dc:creator><description>&lt;p&gt;Looks like a useful pattern, but your particular motivating example is slightly shot down by your own final point&lt;/p&gt;
&lt;p&gt;When you say in the example &amp;quot;// what type should ??? be?&amp;quot;, the answer is given by &lt;/p&gt;
&lt;p&gt;&amp;quot;CONSIDER using a non-generic root type, if such type is already available.&lt;/p&gt;
&lt;p&gt;For example, List&amp;lt;T&amp;gt; implements IEnumerable for the purpose of simulating covariance.&amp;quot;&lt;/p&gt;
&lt;p&gt;??? should be IEnumerable. End of story in the context of that example.&lt;/p&gt;</description></item><item><title>re: Simulated Covariance for .NET Generics</title><link>http://blogs.msdn.com/kcwalina/archive/2008/04/02/SimulatedCovariance.aspx#8353215</link><pubDate>Thu, 03 Apr 2008 10:10:33 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8353215</guid><dc:creator>Chris Nahr</dc:creator><description>&lt;p&gt;&amp;quot;CONSIDER using a non-generic root type, if such type is already available.&amp;quot;&lt;/p&gt;
&lt;p&gt;Why would you restrict this recommendation to *available* non-generic interfaces? &amp;nbsp;IFoo&amp;lt;Object&amp;gt; doesn't look right to me. &amp;nbsp;Using Object as a type parameter clashes with the concept of .NET generics since every type is always an Object anyway.&lt;/p&gt;
&lt;p&gt;Using &amp;lt;Object&amp;gt; would make sense if you could create a universally compatible &amp;quot;base type&amp;quot; from the *existing* generic type, but as you point out that's not possible -- you have to define a new interface anyway. &amp;nbsp;And once you do that, why not drop the useless type argument altogether and just say IFoo?&lt;/p&gt;
&lt;p&gt;That's how IEnumerable works for generic collections, and keeping that pattern seems preferable IMO.&lt;/p&gt;</description></item><item><title>re: Simulated Covariance for .NET Generics</title><link>http://blogs.msdn.com/kcwalina/archive/2008/04/02/SimulatedCovariance.aspx#8353286</link><pubDate>Thu, 03 Apr 2008 11:24:52 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8353286</guid><dc:creator>Hardeep Virdee</dc:creator><description>&lt;p&gt;Thanks for sharing - this is a great pattern which I have already found useful. Would have been a great addition to the book.&lt;/p&gt;</description></item><item><title>re: Simulated Covariance for .NET Generics</title><link>http://blogs.msdn.com/kcwalina/archive/2008/04/02/SimulatedCovariance.aspx#8354924</link><pubDate>Thu, 03 Apr 2008 23:23:04 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8354924</guid><dc:creator>Ryanoffski</dc:creator><description>&lt;p&gt;Regarding the first example:&lt;/p&gt;
&lt;p&gt;List&amp;lt;string&amp;gt; names = new List&amp;lt;string&amp;gt;();&lt;/p&gt;
&lt;p&gt;IEnumerable&amp;lt;object&amp;gt; objects = names; // this won’t compile&lt;/p&gt;
&lt;p&gt;foreach(object obj in objects){&lt;/p&gt;
&lt;p&gt;	Console.WriteLine(obj.ToString());&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;We can use LINQ to get the code to compile:&lt;/p&gt;
&lt;p&gt;IEnumerable&amp;lt;object&amp;gt; objects = names.Cast&amp;lt;object&amp;gt;();&lt;/p&gt;
&lt;p&gt;We can't achieve complete simulated covariance with Cast method, like what's required in the Foo example, but it's useful in simpler cases.&lt;/p&gt;</description></item><item><title>re: Simulated Covariance for .NET Generics</title><link>http://blogs.msdn.com/kcwalina/archive/2008/04/02/SimulatedCovariance.aspx#8355811</link><pubDate>Fri, 04 Apr 2008 08:57:37 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8355811</guid><dc:creator>michhes</dc:creator><description>&lt;p&gt;Definitely worthy for the book!!!&lt;/p&gt;</description></item><item><title>re: Simulated Covariance for .NET Generics</title><link>http://blogs.msdn.com/kcwalina/archive/2008/04/02/SimulatedCovariance.aspx#8358464</link><pubDate>Sat, 05 Apr 2008 00:45:11 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8358464</guid><dc:creator>kcwalina</dc:creator><description>&lt;p&gt;Larry, thanks for the feedback. I will try to use another example. I agree the list root might be confusing. But, it is a real propblem that we talked at one of the BCL meetings dseveral years ago and decided to have IEnumerable&amp;lt;T&amp;gt; extend IEnumerable (which was not the design early on). If we did not make the decision, you would not be able to use IEnumerable as the root for all collections.&lt;/p&gt;
</description></item><item><title>re: Simulated Covariance for .NET Generics</title><link>http://blogs.msdn.com/kcwalina/archive/2008/04/02/SimulatedCovariance.aspx#8358509</link><pubDate>Sat, 05 Apr 2008 00:52:31 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8358509</guid><dc:creator>kcwalina</dc:creator><description>&lt;p&gt;Chris, the reason I think generic roots are preferable to non-generic roots (unless a non-generic root already exists) is that the CLI standard (and the current CLR implementation) already support variance annotations. If/Once main .NET languages start to support it, IFoo&amp;lt;T&amp;gt; will be much more useful than IFoo.&lt;/p&gt;
</description></item><item><title>re: Simulated Covariance for .NET Generics</title><link>http://blogs.msdn.com/kcwalina/archive/2008/04/02/SimulatedCovariance.aspx#8364657</link><pubDate>Mon, 07 Apr 2008 10:44:02 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8364657</guid><dc:creator>Palladinos Nick</dc:creator><description>&lt;p&gt;One Typo&lt;/p&gt;
&lt;p&gt;var foos = new List&amp;lt;IFoo&amp;gt;()&lt;/p&gt;
&lt;p&gt;You declare the Type IFoo&amp;lt;T&amp;gt;&lt;/p&gt;
&lt;p&gt;and Foo&amp;lt;T&amp;gt; : IFoo&amp;lt;object&amp;gt;&lt;/p&gt;
&lt;p&gt;so, the correct code is&lt;/p&gt;
&lt;p&gt;var foos = new List&amp;lt;IFoo&amp;lt;object&amp;gt;&amp;gt;()&lt;/p&gt;</description></item><item><title>re: Simulated Covariance for .NET Generics</title><link>http://blogs.msdn.com/kcwalina/archive/2008/04/02/SimulatedCovariance.aspx#8365789</link><pubDate>Mon, 07 Apr 2008 19:22:43 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8365789</guid><dc:creator>kcwalina</dc:creator><description>&lt;p&gt;Thanks Nick! I fixed it.&lt;/p&gt;
</description></item><item><title>re: Simulated Covariance for .NET Generics</title><link>http://blogs.msdn.com/kcwalina/archive/2008/04/02/SimulatedCovariance.aspx#8404249</link><pubDate>Thu, 17 Apr 2008 22:01:29 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8404249</guid><dc:creator>chris</dc:creator><description>&lt;p&gt;Did you just write this pattern b/c you just happened to think it up recently, or is this a pattern that's used throughout the framework or other substantial projects that you want to officially codify by adding it to the design guidelines? &amp;nbsp;In the case of the former, I'd prefer to keep the guidelines free of ad-hoc contributions that, while interesting, have not yet stood the test of time (that's makes it suitable for a blog entry but not for an official publication); in the case of the latter -- seems like it would be a decent addition -- particularly if you could cite examples of places/types in the framework or other major projects that implement the pattern.&lt;/p&gt;</description></item><item><title>A rash of bloggers</title><link>http://blogs.msdn.com/kcwalina/archive/2008/04/02/SimulatedCovariance.aspx#8502676</link><pubDate>Wed, 14 May 2008 07:34:31 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8502676</guid><dc:creator>GarethJ's WebLog</dc:creator><description>&lt;p&gt;Just lately there seems to be a veritable feast of new blog stuff about VSX (if you don't mind me switching&lt;/p&gt;
</description></item><item><title>re: Simulated Covariance for .NET Generics</title><link>http://blogs.msdn.com/kcwalina/archive/2008/04/02/SimulatedCovariance.aspx#8543760</link><pubDate>Sat, 24 May 2008 06:11:27 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8543760</guid><dc:creator>Victor Shulman</dc:creator><description>&lt;p&gt;Krzysztof, it's an excellent point, about the potential harm of generalizing a modifiable collection. &lt;/p&gt;
&lt;p&gt;However, if it were possible to generalize at (RO) interface level, that would go a ways toward supporting the &amp;quot;program-to-interface&amp;quot; practice. Here's what I mean:&lt;/p&gt;
&lt;p&gt;public interface IDisplayable {&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;string Text { get; }&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;string Data { get; }&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;public class Base : IDisplayable {&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;public string Text { get { return Name; } }&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;public string Data { get { return Id.ToString(); } }&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;public string Name { get; set; }&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;public Guid Id { get; set; }&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;class Sub : Base {&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;...&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;public IList&amp;lt;IDisplayable&amp;gt; GetData()&lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;return [...].ToList&amp;lt;Base&amp;gt;();&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;or:&lt;/p&gt;
&lt;p&gt;public void FillGrid(IList&amp;lt;Base&amp;gt; source);&lt;/p&gt;
&lt;p&gt;public void ShowData() &lt;/p&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;FillGrid([...].ToList&amp;lt;Sub&amp;gt;());&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;In the first example, we have a syntactically RO interface -- no chance of danger at all!&lt;/p&gt;
&lt;p&gt;The second example, admittedly, is iffier: from the reading of it, we assume that there's no updates to the list, though nothing prevents us from sneaking in some silliness. Perhaps, the second example ought to be handled with an RO interface, as well.&lt;/p&gt;
&lt;p&gt;In any case, my point is that, if we can assure the RO quality of the generalized collection, the language should be happy to support our desire to generalize, no?&lt;/p&gt;
&lt;p&gt;Cheers,&lt;/p&gt;
&lt;p&gt;Victor.&lt;/p&gt;</description></item></channel></rss>