Saturday, April 30, 2011

Why is conversion between with different type parameters is NOT allowed?

I just don't get it as it would be so useful to convert one generic container into the other?

Stack <IType> stack = new Stack<SomeType>();
From stackoverflow
  • Are you talking about conversions like so?

    IFoo<Child> child = ...;
    IFoo<Parent> parent = child;
    

    If so, this is what is known as covariance. This is usually paired with it's counterpart contravariant. This feature is indeed not available in the current version of C#. But it will be available in next version of both C# and VB.Net.

    Some articles about the upcoming release

  • While what @JaredPar says is true, there are some work-arounds for collections that are available today. For instance, you can use the Cast IEnumerable extension if there is a legal cast from one type to another.

    List<Foo> list = barList.Cast<Foo>().ToList();
    

    Or you could explicitly convert from one type to another using Select.

    List<double> dList = intList.Select( i => Convert.ToDouble( i ) ).ToList();
    

    Note that both of these methods will produce a new collection of the appropriate type, not simply assign the collection to a variable of a different type as will be available under certain conditions in the next versions of C#/VB.

  • With regard to the example you gave:

    Stack <IType> stack = new Stack<SomeType>();
    

    What would happen if we did this:

    stack.Add(new SomeOtherTypeNotDerivedFromSomeType());
    

    This is the basic reason why covariance is not allowed in .Net, I guess because the underlying collection for the generic container does not necessarily match the declared type. The articles by Eric Lippert go into great detail (more than I really can).

    JaredPar : It's actually allowed in IL starting with 2.0. It's just that none of the compilers take advantage of it

0 comments:

Post a Comment