T in IC<T> requires IB<IA> . You gave him IB<A> . You have no guarantee that IB<A> can be used as IB<IA> only because A implements IA .
Think of it this way: if IB<T> means "I can eat something like T," and IA means "I am the fruit," and A means "apple," then IB<IA> means "I can eat fruit." , and IB<A> means "I can eat any apple." If some code wants to feed you with bananas and grapes, then he needs to take IB<IA> , not IB<A> .
Suppose that IB<A> can be converted to IB<IA> and see what is wrong:
class AppleEater : IB<Apple> { public Apple a_val { get; set; } } class Apple : IA { public int val { get; set; } } class Orange : IA { public int val { get; set; } } ... IB<Apple> iba = new AppleEater(); IB<IA> ibia = iba;
And now we just set iba.val , which is an Apple type property to reference an object of type Orange .
That is why conversion must be illegal.
So how can you make this legal?
Since the code is worth it, you cannot, because, as I just showed, it is not typical.
You can make this legal by marking T as out as follows: interface IB<out T> . However, then using T in any "input context" is prohibited. In particular, you cannot have any property of type T that has a setter. If we make this restriction, the problem will disappear because a_val cannot be set to an instance of Orange , because it is read-only.
This question is asked very often on SO. Look for "covariance and contravariance" questions in C # for many examples.