I'm having difficulties understanding how to use subtypes of a generic type.
Suppose the following situation
public abstract class A { }
public class B : A { }
public abstract class WrapperA<T> where T :A { }
public class WrapperB : WrapperA<B> { }
I have a generic class WrapperA<T>
that has been contstrain to only have class A
or cubtypes of class A
as generic type T
I also have a class UserA
that requires a WrapperA
element in it's constructor.
public abstract class UserA
{
protected UserA(WrapperA input) { }
}
I tried the above, but that won't fly. This gives me the error:
Error CS0305 Using the generic type 'WrapperA<T>' requires 1 type arguments
I actually don't care which specific WrapperA
object I get here, but I can set it to the parentclass A as I'm sure that the generic parameter will either be A
, or a subtype of A
, so we adjust as follows
public abstract class UserA
{
protected UserA(WrapperA<A> input) { }
}
Fine, no more errors so far.
But now I want to make a subclass of UserA
, UserB
that needs a 'WrapperB' as input.
public class UserB : UserA
{
protected UserB(WrapperB input) : base(input) { }
}
Now this gives me the error:
Error CS1503 Argument 1: cannot convert from 'WrapperB' to 'WrapperA<A>'
Why can't it convert WrapperB
to WrapperA<A>
I would think that should be possible, since WrapperB
is a subtype of WrapperA
and the type parameter B
is a subtype of A
(which it must be because of the constraint)
Is my reasoning flawed, or is this just a limitation of the compiler?
If found a workaround by defining an interface public interface IWrapperA
and letting my IWrapperA
implement this interface. Now i can use the IWrapperA as a parameter in my constructor, but this feels like a hacky workaround that I shoudn't need
public interface IWrapperA { }
public abstract class WrapperA<T> : IWrapperA where T :A { }
public abstract class UserA
{
protected UserA(IWrapperA input) { }
}
public class UserB : UserA
{
protected UserB(WrapperB input) : base(input) { }
}
What would be a better, more elegant way to solve this problem?