Мне нужна улучшенная производительность Activator.CreateInstance() и встретил эту статью от Мирона Абрамсона, который использует factory для создания экземпляра в ИЛ, а затем кешировать его. (Я включил код ниже с сайта Мирона Абрамсона, если он каким-то образом исчезнет). Я новичок в коде IL Emit и ничего кроме Activator.CreateInstance() для создания экземпляра класса, и любая помощь будет очень благодарна.
Моя проблема в том, что мне нужно создать экземпляр объекта, который принимает ctor с параметром. Я вижу, что есть способ передать тип параметра, но есть ли способ передать значение параметра ctor?
Если возможно, я хотел бы использовать метод, аналогичный CreateObjectFactory<T>(params object[] constructorParams)
, поскольку некоторые объекты, которые я хочу создать, могут иметь более 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;
}
}
Обновить код Miron от комментатора на своем сообщении 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>));
}
}