I have a generics class with a subclass that provides specific types.
public abstract class GenericBase<T>
where T:Interface1
{
}
I subclass the generics with specific implementations:
public class Customer:
GenericBase<Type1>
(Type1
implements Interface1
).
I have another abstract base class that has a reference to this:
protected GenericBase<Interface1> genericInstance;
Finally, when I attempt to assign the genericInstance to an instance of the base class, it gives me a compiler error, saying that it "cannot implicitly convert Customer to GenericBase<Interface1>".
base.genericInstance = new Customer(); //Compiler error
I don't understand why I would get this error if Customer
is a subtype of GenericBase<Type1>
, and Type1
implements Interface1
. Isn't Customer
effectively a type of GenericBase<Interface1>
, if it's a subclass of GenericBase<Type1>
?
I assume I'm misunderstanding something about generics here; is there a way to allow this behavior?
In C#, covariance (assigning a derived type to a base type) cannot be applied to generic classes. As a result, you would need to apply an interface specifically marked as covariant, using the out parameter modifier on a new IGenericBase
interface.
protected IGenericBase<Interface1> genericInstance = new Customer();
public interface IGenericBase<out T> {}
public abstract class GenericBase<T> : IGenericBase<T>
where T:Interface1 {}
public interface Interface1 {}
public class Type1 : Interface1 {}
public class Customer: GenericBase<Type1> {}
C# doesn't have covariance of generic classes, which basically means you cannot assign a value with a more derived type argument to a variable with a less derived type argument.
That would work with interfaces, though, provided some conditions are satisfied, namely, if the parameter-type is used in covariant positions only, i.e. as a return type of methods and properties.
Refer to this and other bits of documentation for more info.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With