我知道Activator.CreateInstance()
可以创建object
的新实例。但我正在寻找一种通过IL
和Expression
创建实例的方法。我想我可以创建一个动态lambda来创建一个类型的实例,并缓存lambda以加速对象初始化。我对吗?你能帮帮我吗?
答案 0 :(得分:4)
您可以使用Expression.New()
表示对象的创建。您可以向其传递具有无参数构造函数的Type
或ConstructorInfo
,以及表示构造函数参数的Expression
。如果您想要返回object
,并且希望它也适用于值类型,则还需要添加Expression.Convert()
。
总而言之,相当于Activator.CreateInstance()
的内容可能如下所示:
object CreateInstance(Type type)
{
return Expression.Lambda<Func<object>>(
Expression.Convert(Expression.New(type), typeof(object)))
.Compile()();
}
如果您想在IL中执行相同操作,则需要使用the newobj
instruction作为参考类型。如果要对值类型执行相同操作,可以创建该类型的局部变量,将其装入并将其返回:
object CreateInstance(Type type)
{
var method = new DynamicMethod("", typeof(object), Type.EmptyTypes);
var il = method.GetILGenerator();
if (type.IsValueType)
{
var local = il.DeclareLocal(type);
// method.InitLocals == true, so we don't have to use initobj here
il.Emit(OpCodes.Ldloc, local);
il.Emit(OpCodes.Box, type);
il.Emit(OpCodes.Ret);
}
else
{
var ctor = type.GetConstructor(Type.EmptyTypes);
il.Emit(OpCodes.Newobj, ctor);
il.Emit(OpCodes.Ret);
}
return method.Invoke(null, null);
}