This question already has an answer here:
I was going through Asp.Net MVC lesson and learned that, for a method to qualify as an action for a controller,
- It must not have an "open generic type"
I understand generics somewhat and use them to some extent, but:
- What is an open generic type in .Net.
- Is there such a thing as a closed generic type?
- Open generic type is a term not used very often. What is used / confused with it ?
The C# language defines an open type to be a type that's either a type argument or a generic type defined with unknown type arguments:
Therefore
T
,List<T>
, andDictionary<string,T>
, andDictionary<T,U>
are all open types (T
andU
are type arguments) whereasList<int>
andDictionary<string,int>
are closed types.There's a related concept: An unbound generic type is a generic type with unspecified type arguments. An unbound type can't be used in expressions other than
typeof()
and you can't instantiate it or call its methods. For instance,List<>
andDictionary<,>
are unbound types.To clarify the subtle distinction between an open type and an unbound type:
If you run this snippet, it'll print out
which is the CLR name for
List<int>
. It's clear at runtime that the type argument isSystem.Int32
. This makesList<T>
a bound open type.At runtime, you can use reflection to bind type arguments to unspecified type parameters of unbound generic types with the
Type.MakeGenericType
method:You can check whether a type is an unbound generic type (generic type definition) from which you can construct bound types with the
Type.IsGenericTypeDefinition
property:To get the unbound type from a constructed type at runtime, you can use the
Type.GetGenericTypeDefinition
method.Note that for a generic type, you can either have a completely unbound type definition, or a completely bound definition. You can't bind some type parameters and leave others unbound. For instance, you can't have
Dictionary<int,>
orDictionary<,string>
.Just to add:
Dictionary<string, T>
(or more preciselyDictionary<string,>
) is still an open type.Example:
There are three kinds of generic types. To make it short, in this (simplified) declaration:
Dictionary<TKey, TValue>
is an unbounded generic type.KeyValuePair<TKey, TValue>
is, in this case, an open constructed generic type. It has some type parameters, but they are already defined elsewhere (in Dictionary, in this case).Dictionary<string, int>
would be a closed constructed generic type.An "open generic type" is just a generic type that doesn't yet have its type specified (e.g.,
CargoCrate<T>
). It becomes "closed" once a concrete type has been assigned (e.g.CargoCrate<Widget>
).For example, say you have something like this:
Here,
picnicBasket
's type is open: nothing's yet been assigned toT
. When you make a concrete PicnicBlanket with a specific type -- for example, by writingPicnicBlanket<Food> p = new PicnicBlanket<Food>()
-- we now call it closed.