Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you subclass a generics class with a specific typed class?

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?

like image 527
GendoIkari Avatar asked Sep 23 '15 20:09

GendoIkari


2 Answers

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> {}
like image 155
David L Avatar answered Oct 19 '22 21:10

David L


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.

like image 30
Gebb Avatar answered Oct 19 '22 20:10

Gebb