I know that Activator.CreateInstance()
can create a new instance of an object
. But I'm searching for a way to create an instance by IL
and Expression
. I think I can create a dynamic lambda to create an instance of a type, and cache the lambda to speed up objects initialization. Am I right? Can you help me please?
Asked
Active
Viewed 2,362 times
3
-
Duplicate http://stackoverflow.com/questions/9788813/best-way-to-create-an-instance-of-run-time-determined-type/9789971#9789971 – Serj-Tm Apr 03 '12 at 16:41
1 Answers
5
You can represent creation of an object using Expression.New()
. You can pass to it either a Type
that has parameterless constructor, or a ConstructorInfo
, along with Expression
s representing the constructor parameters. If you want to return an object
and you want it to work for value types too, you also need to add an Expression.Convert()
.
Putting it all together, the equivalent to Activator.CreateInstance()
could look like this:
object CreateInstance(Type type)
{
return Expression.Lambda<Func<object>>(
Expression.Convert(Expression.New(type), typeof(object)))
.Compile()();
}
If you want to do the same in IL, you need to use the newobj
instruction for reference types. If you want to do the same for values types, you can create a local variable of that type, box it and return it:
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);
}

svick
- 236,525
- 50
- 385
- 514
-
Thanks I understand it. So if the constractor has some arguments, how can I provide theme? Another Q is that where can I learn about `Expression`? Where did you learn it? Thanks in advance – amiry jd Apr 03 '12 at 17:05
-
Everything you need to know about various .Net types is [at MSDN](http://msdn.microsoft.com/en-us/library/gg145045.aspx), including [the documentation for `Expression`](http://msdn.microsoft.com/en-us/library/bb356138.aspx). And like I said, you can provide parameters to the constructor as parameters to the `New()` method, probably using `Expression.Constant()`. – svick Apr 03 '12 at 17:09