In one of my previously published article (very old 🙂 one), I mentioned briefly about reflection, and discuss how reflection is an important concept in .Net Framework. While it is a very important concept there is a performance issue related with the Reflection. If you over use reflection codes in your projects you have to face with performance issues compared with the code that is implemented in this sample project.
In that context, I have explained two methods to have a better performance when manipulating objects dynamically and I have shared code examples about them. As a summary, I created a ObjectCreateMethod class which uses DynamicMethods and creates an IL which calls type constructors. By calling that generated DynamicMethod we can create instance of types faster than traditional reflection. If you are interested in and need more information, you can access article from here.
After reviewing previous article, now you are ready to get more information about the usage of the DynamicMethods that improve the performance of traditional reflection which is the subject of this article.
In the previous article, maybe you have discerned an imperfection. The ObjectCreateMetod class – which uses DynamicMethods for creating instance of a type – is only suitable for creating instance of types which has parameter-less constructors.
While I was surfing the web, I found a feedback about my article. Someone asks if it is possible to use ObjectCreateMethod class with types which has parameterized constructors. Because of this, I decided to updated my code, and now it also supports the constructors with parameter(s).
To resolve this issue I created a dynamic method which takes object[] argument as the constructor arguments. Than I take these parameters on to the stack and call new opcode. Here is the code;
/// <summary>
/// Creates the dynamic proxy method which calls given <see cref="ConstructorInfo"/>
/// </summary>
/// <param name="methodInfo"></param>
private static DynamicMethodDelegate CreateProxyMethod(ConstructorInfo constructor)
{
var method = new DynamicMethod(constructor.DeclaringType.Name + "_ctor_Proxy",
typeof(object),
new Type[] { typeof(object[]) },
constructor.DeclaringType);
var wrapper = new ILGeneratorWrapper(method.GetILGenerator());
var parameters = constructor.GetParameters();
var parameterTypes = new Type[parameters.Length + 1];
parameterTypes[0] = constructor.DeclaringType;
for (int i = 0; i < parameters.Length; i++)
{
parameterTypes[i + 1] = parameters[i].ParameterType;
}
wrapper.DeclareLocals(parameterTypes);
for (int i = 1; i < parameterTypes.Length; i++)
{
wrapper.EmitLoadArg(0);
wrapper.EmitLoadCons(i - 1);
wrapper.Emit(OpCodes.Ldelem_Ref);
wrapper.EmitCast(parameterTypes[i]);
wrapper.EmitStoreLocal(i);
}
for (int i = 1; i < parameterTypes.Length; i++)
{
wrapper.EmitLoadLoc(i);
}
wrapper.Emit_NewObj(constructor);
wrapper.EmitStoreLocal(0);
wrapper.EmitLoadLoc(0);
wrapper.Emit(OpCodes.Ret);
return method.CreateDelegate(typeof(DynamicMethodDelegate)) as DynamicMethodDelegate;
}
I also added some other helper proxy classes which provides invoking other type members (fields, properties and methods) by using DynamicMethods too.