Co- and contra-variance (Lucian Wischik)

Co- and contra-variance (Lucian Wischik)

  • Comments 10

How do I convert an IEnumerable(Of CheckingAccount) into an IEnumerable(Of Account) ? (where CheckingAccount inherits from Account).

Currently this conversion isn't allowed, but we're considering a VB language feature to support it. The topic is called "co- and contravariance", and has been in the CLR since 2005 or so, but no one's yet released a .Net language that uses it. Eric Lippert has written a series of blog posts to explore how variance might appear in a hypothetical future version of C# and gather feedback, and I'm going to do the same for VB.

Dim args As New List(Of ConstantExpression)
args.Add(Expression.Constant(2))
args.Add(Expression.Constant(3))
Dim y = Expression.Call(instance, method, args)

Here above is a practical need I had for variance last week. The problem is that "args" is a List(Of ConstantExpression), but the "Expression.Call" is expecting just an IEnumerable(Of Expression), and so we can't do it. But it should really work! since the code is typesafe, and the CLR already supports this kind of conversion anyway.

What we have in mind is... well, it's too long to fit in a blog post so I've written it up here: VB Variance.

Our goal in writing about this now is to get feedback on our designs from potential users. So please, add your comments!

Leave a Comment
  • Please add 5 and 6 and type the answer here:
  • Post
  • PingBack from http://hoursfunnywallpaper.cn/?p=234

  • The easy way to do this at the moment is the following:

    <System.Runtime.CompilerServices.Extension()> _

       Public Function ToIEnumerable(Of T)(ByVal args As IEnumerable) As IEnumerable(Of T)

           Return (From item As Object In args Select DirectCast(item, T))

       End Function

    Quick and simple. Your original code would just change to the following:

    Dim y = Expression.Call(instance, method, args.ToIEnumerable(Of Expression))

  • Damien Guard came up with a solution to this:

    http://damieng.com/blog/2006/05/24/ienumerable_t_to_ienumerable_subclassoft

  • Lucian has kicked off the conversation on generic variance in VB , so I thought I’d write a few posts

  • It seems to me that declaration-site variance (as implemented in the CLR, and now proposed for C# and VB.NET) is less useful than call-site variance (as implemented in Java using wildcards). Here's why: stop for a moment and think, how many of BCL generic classes could actually be converted to use this feature? There's IEnumerable<T>, alright - but what else? ICollection<T> is right out, because it is IEnumerable<T> (and hence covariant), but it also takes T as an argument for Add() (which is contravariant) - the intersection of those is invariant. The same goes for all interfaces further extending ICollection<T>, such as IList<T>.

    On the other hand, with wildcards, I can deal with ICollection<T> either in covariant or contravariant fashion: for example, only using GetEnumerator() and Count - a typical real-world scenario - is covariant; only using Add() is contravariant. You can do this with declaration-site variance too, but you have to split every interface into its covariant and contravariant parts, and I doubt the BCL team would do it at this point; besides, it relies upon interface designers to do the right thing, and gives the user no recourse if they don't.

  • Lucian has kicked off the conversation on generic variance in VB , so I thought I’d write a few posts

  • Last week at the Professional Developers Conference , we made a number of very exciting announcements

  • Last week at the Professional Developers Conference , we made a number of very exciting announcements

  • Nous voici quasiment au terme des nouveautés de Visual Basic 2010 (VB10). Abordons cette fois-ci la notion

  • ok i will check the blog link, thanks

Page 1 of 1 (10 items)