Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Call Activator.CreateInstance, passing a Method as Constructor Argument?

How can the following be created via reflection?

var t = new SomeFrameworkType<string, string>(s => MyClass.MyMethod(s));

Here's what I have so far:

var typeParamOne = Type.GetType("System.String");
var typeParamTwo = Type.GetType("System.String");
var myClass= Type.GetType("ConsoleApplication.MyClass");
var myMethod = myClass.GetMethod("MyMethod");
var type = typeof(SomeFrameworkType<,>);
var typeArgs = new[] {typeParamOne, typeParamTwo };
var constructed= type.MakeGenericType(typeArgs);
var instance = Activator.CreateInstance(constructed, myMethod);

The sample is the way it is as most of the required info will not be known and will be supplied as parameters.

Now, the "instance" assignation will throw an exception. How can I appropriately pass through to the constructor?

Also, how would I cast the result to SomeFramework so I can work with it when I don't know the type parameters?

Thanks!

like image 618
Richard Avatar asked Jan 06 '14 14:01

Richard


People also ask

Does activator CreateInstance call constructor?

The Activator. CreateInstance method creates an instance of a type defined in an assembly by invoking the constructor that best matches the specified arguments. If no arguments are specified then the constructor that takes no parameters, that is, the default constructor, is invoked.

What is activator CreateInstance in C#?

Creates an instance of the specified type using the constructor that best matches the specified parameters. CreateInstance(Type, Object[], Object[]) Creates an instance of the specified type using the constructor that best matches the specified parameters.


1 Answers

Assuming SomeFrameworkType<,> definition is something like the following:

class SomeFrameworkType<T1, T2> { 
  public SomeFrameworkType(Func<T1, T2> func) {}
}

and the generic type parameters for T1 and T2 are System.String (like in OP's example), then it can be instantiated via reflection using the following codes:

var typeParamOne = typeof (string);
var typeParamTwo = typeof(string);
var myClass = typeof(ConsoleApplication.MyClass);
var myMethod = myClass.GetMethod("MyMethod");
var type = typeof(SomeFrameworkType<,>);
var typeArgs = new[] { typeParamOne, typeParamTwo };
var constructed = type.MakeGenericType(typeArgs);

// construct the delegate
var ctrArgs = typeof(Func<,>).MakeGenericType(typeArgs);
var dlgate = Delegate.CreateDelegate(ctrArgs, myMethod);

var instance = Activator.CreateInstance(constructed, dlgate);

AFAIK, we need to know at least the generic type parameters for casting the resulting object to SomeFrameworkType<,> or (as pointed by Jon G) use the non-generic base type of SomeFrameworkType<,> if any.

var casted = instance as SomeFrameworkType<string, string>;
like image 100
IronGeek Avatar answered Oct 12 '22 23:10

IronGeek