How to pass ctor args in Activator.CreateInstance?
Posted
by thames
on Stack Overflow
See other posts from Stack Overflow
or by thames
Published on 2010-01-07T23:20:37Z
Indexed on
2010/06/02
3:13 UTC
Read the original article
Hit count: 376
I need a performance enhanced Activator.CreateInstance() and came across this article by Miron Abramson that uses a factory to create the instance in IL and then cache it. (I've included code below from Miron Abramson's site in case it somehow disappears). I'm new to IL Emit code and anything beyond Activator.CreateInstance() for instantiating a class and any help would be much appreciative.
My problem is that I need to create an instance of an object that takes a ctor with a parameter. I see there is a way to pass in the Type of the parameter, but is there a way to pass in the value of the ctor parameter as well?
If possible, I would like to use a method similar to CreateObjectFactory<T>(params object[] constructorParams)
as some objects I want to instantiate may have more than 1 ctor param.
// Source: http://mironabramson.com/blog/post/2008/08/Fast-version-of-the-ActivatorCreateInstance-method-using-IL.aspx
public static class FastObjectFactory
{
private static readonly Hashtable creatorCache = Hashtable.Synchronized(new Hashtable());
private readonly static Type coType = typeof(CreateObject);
public delegate object CreateObject();
///
/// Create an object that will used as a 'factory' to the specified type T
///
public static CreateObject CreateObjectFactory() where T : class
{
Type t = typeof(T);
FastObjectFactory.CreateObject c = creatorCache[t] as FastObjectFactory.CreateObject;
if (c == null)
{
lock (creatorCache.SyncRoot)
{
c = creatorCache[t] as FastObjectFactory.CreateObject;
if (c != null)
{
return c;
}
DynamicMethod dynMethod = new DynamicMethod("DM$OBJ_FACTORY_" + t.Name, typeof(object), null, t);
ILGenerator ilGen = dynMethod.GetILGenerator();
ilGen.Emit(OpCodes.Newobj, t.GetConstructor(Type.EmptyTypes));
ilGen.Emit(OpCodes.Ret);
c = (CreateObject)dynMethod.CreateDelegate(coType);
creatorCache.Add(t, c);
}
}
return c;
}
}
Update to Miron's code from commentor on his post 2010-01-11
public static class FastObjectFactory2<T> where T : class, new()
{
public static Func<T> CreateObject { get; private set; }
static FastObjectFactory2()
{
Type objType = typeof(T);
var dynMethod = new DynamicMethod("DM$OBJ_FACTORY_" + objType.Name, objType, null, objType);
ILGenerator ilGen = dynMethod.GetILGenerator();
ilGen.Emit(OpCodes.Newobj, objType.GetConstructor(Type.EmptyTypes));
ilGen.Emit(OpCodes.Ret);
CreateObject = (Func<T>)
dynMethod.CreateDelegate(typeof(Func<T>));
}
}
© Stack Overflow or respective owner