Question

Referring to the answer by Jon Skeet here: Pass An Instantiated System.Type as a Type Parameter for a Generic Class

I need to load a Generic type based on the name of the generic type, and the name of the type that is the type parameter for the generic. So from Jon's example I would have:

string genName = "MyNamespace.Generic";
string itemName = "System.String";

I have the following code that will load a type based on the name of the type and a fully justified assembly name/path. It works fine for "simple types"

public Type GetTypeOf(string assemblyPath, string className)
{
    var asmbly = System.Reflection.Assembly.LoadFrom(assemblyPath); //open assembly
    return asmbly.GetType(className, true, true); //throws error, not case sensitive
}

I was hoping to use this as follows:

//Get the types
var genTyp = GetTypeOf(genPath,genName);
var itemTyp = GetTypeOf(itemPath,itemName);

//Put them together:
var typ = getType.MakeGenericType(itemTyp);

This falls over on the first line with a System.TypeLoadException stating:

Could not load type <TypeName here> from assembly <AssemblyName here>

I've tried a number of permutations of creating the generic, included supplying the full class name MyNamespace.Generic<System.String>. It works correctly when I specify a non-generic type to load from the same assembly that contains the generic type.

Was it helpful?

Solution

Unfortunately, using GetType with generic types is not that readable. You have to use the full qualified type name, even for the generic parameters:. For example, TestType<object> reads like this:

TestType`1[[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]

Your sample code does not include the type declarations, so you have to play around with this. You can try this code snippet and take a look what the debugger says:

string typeName = typeof(MyNamespace.Generic<>).Name;
string fullTypeName = typeof(MyNamespace.Generic<>).FullName;

The results should help you getting the correct type name.

OTHER TIPS

Based on Carsten's answer above, I've adapted my GetTypeOf method as follows:

    public Type GetGenericTypeOf(string assemblyPath, string genericClass, string itemQualifiedClass)
    {
        string typString = String.Format("{0}`1[[{1}]]",genericClass,itemQualifiedClass)
        var asmbly = System.Reflection.Assembly.LoadFrom(assemblyPath); //open assembly
        return asmbly.GetType(typString, true, true); //throws error, not case sensitive
    }

I can then use it as follows:

var itemTyp = GetTypeOf(itemPath,itemName);
var genTyp = GetGenericTypeOf(genPath,genName,itemTyp.AssemblyQualifiedName);

//This genTyp is then good to go:
var genInst = Activator.CreateInstance(getTyp);

There's no need for MakeGenericType as the genType returned bypasses this step.

I've now done a full write up of this, including VB.Net version of the code on my blog here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top