Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic contraints on derived classes

I have class A:

public class ClassA<T>

Class B derives from A:

public class ClassB : ClassA<ClassB>

Class C derives from class B:

public class ClassC : ClassB

Now I have a generic method with constraints

public static T Method<T>() where T : ClassA<T>

OK, now I want to call:

ClassC c = Method<ClassC>();

but I get the compile error saying: Type argument 'ClassC' does not inherit from or implement the constraint type 'ClassA<ClassC>.

Yet, the compiler will allow:

ClassB b = Method<ClassB>();

My understanding is that this fails because ClassC inherits ClassA<ClassB> instead of ClassA<ClassC>

My real question is, is it possible to create a class deriving from ClassB that can be used in some way with the generic method?

This may seem like generics are overused and I would agree. I am trying to create business layer objects deriving from the subsonic data objects in a separate project.

Note: I have put the < T > with extra spaces otherwise they get stripped from the question.

like image 656
ptutt Avatar asked Oct 24 '08 12:10

ptutt


Video Answer


2 Answers

Well, you could change Method to:

public static T Method<T,U>() where T : ClassA<U> where U : T

Does that help at all? It's not much use if you can't change Method of course...

like image 145
Jon Skeet Avatar answered Sep 24 '22 13:09

Jon Skeet


No. You must change or wrap this method.

Here is the reason.

ClassC inherits from ClassB which inherits from ClassA(ClassB)

ClassC does not inherit from ClassA(ClassC)

No child of ClassB will inherit from ClassA(child class), because they instead inherit from ClassB and ClassB does not inherit from ClassA(child class).

Generic types are invariant.

like image 21
Amy B Avatar answered Sep 23 '22 13:09

Amy B