Reputation: 11914
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?
Upvotes: 9
Views: 5225
Reputation: 33815
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> {}
Upvotes: 12
Reputation: 6546
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.
Upvotes: 4