Covariance/Contravariance Conundrum when using generic interface constraints?

Your IFoo interface seems to be wrong in this usage, it should be: public interface IFoo hmm = new MyFoo() So it can't make the implicit conversion. If you really want to be able to widen this interface implicitly, the second type argument should be out instead of in Update: after your comments, I see that the big dilemma is that you want it to be both in and out, which isn't really possible Since it's a contravariant input, you can't assign the interface covariantly to IFoo.

Your IFoo interface seems to be wrong in this usage, it should be: public interface IFoo With U being out. Remember that an out generic type parameter means that it can vary "outwards". That is, you can widen the type implicitly to a wider type.In, though, means that you can implicitly narrow the type "inwards" to a more specific type.

These are just rough analogies, of course. So in the case of the assignment of hmm, you are are implicitly trying to widen the interface generic type parameter for U from Derived to Base, but the interface declares it to be narrowing (in): IFoo hmm = new MyFoo(); So it can't make the implicit conversion. If you really want to be able to widen this interface implicitly, the second type argument should be out instead of in.

Update: after your comments, I see that the big dilemma is that you want it to be both in and out, which isn't really possible Since it's a contravariant input, you can't assign the interface covariantly to IFoo, unfortunately. You either need to code around the fact you can't assign to IFoo or what you could do is create Foo as: public class MyFoo : IFoo And then cast to Rectangle inside the implementation. The main thing is you can't have both covariance and contravariance on the same type parameter.

Does this make sense?

Indeed, that would make sense. However, as U is an input for a method changing it to out yields; Invalid variance: The type parameter 'U' must be contravariantly valid on 'ConsoleApplication3.IFoo. Convert(U)'.'U' is covariant.

– MattC May 25 at 15:51 Good point on that, then the answer would be you can't do it. You can't have a type be both covariant and contravariant.So you'd have to assign hmm to be an IFoo – James Michael Hare May 25 at 18:40 DO you mean cast to Derived inside the implemenation? – MattC May 26 at 14:53.

Something that can convert a Base into a Rectangle will also turn a Derived into an IShape. Something that can convert a Derived into a Rectangle, however, may not be able to do anything useful with a Base. You correctly identified that the covariance specifier for your second parameter needs to be "in", but are then trying to use the covariance in the way opposite what it actually supports.

When you state "...may not be able to do anything useful with a Base", the interface has a constraint that U has to be at least of ttype Base so I would expect anything that implements interface IFoo to know how to deal with Base. – MattC May 26 at 8:36 Something that can accept a base type as a parameter can accept a derived type, but the reverse is not true. Something that knows how to handle every ToyotaTercel may not know how to deal with a FordTaurus, even though both ToyotaTercel and FordTaurus derive from Car.

Your MyFoo class accepts objects of type Derived. It could also accept objects of sub-derived types. It can't deal with objects of type Base.

– supercat May 26 at 16:30.

If you really want to be able to widen this interface implicitly, the second type argument should be out instead of in. Update: after your comments, I see that the big dilemma is that you want it to be both in and out, which isn't really possible Since it's a contravariant input, you can't assign the interface covariantly to IFoo, unfortunately. And then cast to Rectangle inside the implementation.

The main thing is you can't have both covariance and contravariance on the same type parameter. Does this make sense?

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions