2

In my C# code I have the following hierarchies (I've ommited unnecessary keywords for clarity):

B : A
C : B
D : C

L<T> : K where T : C
M : L<D>

Now I get a casting error:

L<C> c = new M       -- error

This passes ok:

L<D> a = new M       --  ok
C b = new D          --  ok

Why do I get this error on type L<C> ? Clearly M, which is L<D> can be followed back to L<C> since D : C.. but why is this an error? Also, if this error is correct, how do I avoid such errors?

UPDATE:

Also presenting runnable (i hope :)) code version:

public abstract class A {}
public class B : A {}
public class C : B {}
public class D : C {}

public abstract class K {}
public class L<T> : K where T : C {}
public class M : L<D> {}

// -- ok:

L<D> a = new M();       //  ok
C b = new D();          //  ok

// -- error:

L<C> c = new M();       //  error

UPDATE 2

My vote for reopening is based on the fact that the thread marked as the "duplicate" of this question describes a little different situation with collections, where it is possible and clear how to cast between collection types because collection elements can be cast easily. However in my case this is not so and that solution won't work. So I vote for someone to either 1) give a proper solution 2) explain how can the solution from the referred thread be applied here 3) explain, why there is no solution.

noncom
  • 4,962
  • 3
  • 42
  • 70
  • 1
    It would really help if you could produce code that could be tested, although minimal in nature. – Lasse V. Karlsen Jun 05 '14 at 20:10
  • 1
    You should look up covariance and contravariance, in fact this is almost certainly a duplicate of existing questions here on SO. – Lasse V. Karlsen Jun 05 '14 at 20:11
  • @LasseV.Karlsen Hey, I spent some more time with this and still I do not get it. In the example you have refered to, there is a list where every single item can be converted to the required class. But in my example, the instance of the class cannot be extracted as easily as from the List<> class.. In other words, I still don't get how to deal with this. – noncom Jun 05 '14 at 21:48
  • @noncom: What is `K` in your example? – Radek Jun 06 '14 at 06:56
  • @Radek all of these are classes. But I have missed its definition in the code sample! I have updated it so that now it includes the definition of `K`. – noncom Jun 06 '14 at 07:55
  • @noncom: Are you saying that an `L` cannot be reliably converted into an `L`? – StriplingWarrior Jun 06 '14 at 20:28
  • 2
    An `L` can't be treated as an `L` because an `L` won't accept elements of type `C`, while an `L` will. A conversion probably isn't an appropriate solution either, since converting an `M` to an `L` would likely lose whatever functionality `M` provides. I would suggest changing the variable type to `L : C>` (or the nearest thing in C#; the closest language I know is Java). Alternately, if the features added by `M` really aren't important, you could copy the contents of the `M` into a new `L`. – Brilliand Jun 06 '14 at 20:35

0 Answers0