Interaction of type and method classes

Consider the following class:

public class DerivedClassPool<TBase> where TBase : class { public TBase Get(Type componentType) { // Not important, but you get the idea return Activator.CreateInstance(componentType) as TBase; } public TDerived SomeMethod<TDerived>() where TDerived : TBase { return Get(typeof(TBase)) as TDerived; } } 

Note that I restricted the TBase generic class argument to the class: where TBase : class
I also restricted the TDerived generic method argument to TDerived or something derived from this: where TDerived : TBase .

I get an error in the as TDerived line:

A parameter of type "TDerived" cannot be used with the "as" operator because it does not have a class type restriction or a class restriction

I understand that to prevent the error, I need to add a class constraint, so I would get:

 where TDerived : class, TBase 

Why should I do this when TBase already limited to a class and TDerived is TBase or derived from it?

+8
generics inheritance c #
source share
2 answers

UPDATE: This question was the subject of my blog on September 19, 2011 . Thanks for the great question!


Why should I do this when TBase is already limited to be a class, and TDerived is to be TBase or derived from it?

Because the value type can be obtained from the reference type. int is derived from the reference types object and System.ValueType and implements a number of interfaces. This does not make int reference type.

It is perfectly legal to call SomeMethod<int> on an instance of DerivedClassPool<object> , because int is obtained from an object.

Now there are times when your criticism will be justified. It is possible to construct situations in which two type parameters are connected in such a way that both of them can logically be only reference types, but only one of them is classified by language as “known as a reference type”.

As an exercise for the reader: can you find it? It may be necessary to carefully read section 10.1.5 of the specification in order to accurately define “known as a reference type”.

+8
source share

Because TBase can be an interface, therefore TDerived can be a value type.

+2
source share

All Articles