On reflection and generic Arity

In my comments there is a good discussion going on about reflection and generic arity

J. Ambrose Little asks:

I've got some code that is dynamically compiled and loaded into an Assembly type. In the past, I could use myAssembly.CreateInstance to get an instance of a type in the Assembly. But what if the type I need to create requires a type argument? Is there any way to pass that through reflection to get an instance of the type?

 

I ended up using BindGenericParameters:

System.Type constructedType, genericType;

genericType = compiled.CompiledAssembly.GetType(dynamicTypeName + "`1");

constructedType = genericType.BindGenericParameters(new Type[1] {typeof(T)});

comparer = constructedType.GetConstructor(new Type[0] {}).Invoke(null)

as System.Collections.Generic.IComparer<T>;

I am wondering why I have to add the "`1" at the end of my type name to get the generic. I can see that it indicates the number of type parameters, but the example for BindGenericParameters in the docs didn't, IIRC, add that (so its code shouldn't work). Are you guys going to work around this or is this the format you're sticking with?

From Joel:

Backtick "`" plus integer specifies the arity of the Generic type, and is actually burned in at the metadata level as the string type name. GetType() takes an unmangled string name and simply brings it to life by string comparing over the metadata table. It's unfortunate that we couldn't use angle brackets to specify arity, ala C# syntax, but the C++ folk have already reserved them in the type name grammar. :)

For now, you'll need to specify the string name according to the type name grammar rules (which should be specified in the next revision of the ECMA specification). Which means, Foo`1 for Foo<T>, Foo`2 for Foo<K,V> etc. We may look at adding helper methods for string name mangling sometime in the future.

As always, love to hear your thoughts\comments