[ACCEPTED]-Generics open and closed constructed types-generics

Accepted answer
Score: 85

In practice the terminology doesn't really 15 matter much - I can't remember the last 14 time I had to worry about it except when trying 13 to write about it.

  • An unbound type has no type arguments specified
  • A constructed type has at least one type argument specified
  • A type parameter is an open type
  • An array type where the element type is open is an open type
  • An open constructed type has at least one type argument which is an open type
  • A closed type is any type which isn't open

(There are further rules 12 for nested types. Consult the C# 3.0 spec 11 section 4.4 for gory details.)

As an example 10 of an open constructed type, consider:

public class NameDictionary<T> : Dictionary<string, T>

The 9 base class of typeof(NameDictionary<>) is:

  • Constructed because it specifies type arguments
  • Open because the second type argument (T) is an open type

The MSDN docs for Type.IsGenericType have 8 quite a useful little table.

Just to reiterate, this 7 is almost entirely unimportant in day to 6 day use.

I'm generally in favour of knowing 5 the correct terminology - particularly for 4 things like "pass by reference" etc 3 - but in this case it really, really doesn't 2 come up very often. I would like to actively 1 discourage you from worrying about it :)

Score: 9

From MSDN:

A generic type or method is closed 7 if instantiable types have been substituted 6 for all its type parameters, including all 5 the type parameters of all enclosing types. You 4 can only create an instance of a generic 3 type if it is closed.

So this works as List<int> is 2 closed:

var list = Activator.CreateInstance(typeof(List<int>));

But this throws an exception at run-time 1 because List<> is open:

var list = Activator.CreateInstance(typeof(List<>));
                                               ↑
Score: 3

I have mostly used open generics (basically 8 uninstantiated generics) in dependency injection 7 mappings. For example, something like

Bind<IRepository<>>()
   .To<BasicRepository<>>()

Then, when 6 my object constructor contains:

public SomethingController(IRepository<Something>) { ... }

My dependency 5 injection mechanism will instantiate a BasicRepository< Something 4 > automagically. (This works with Ninject 3 and StructureMap, and probably the Castle 2 Windsor library; I'm not sure about other 1 frameworks).

More Related questions