Ideally I want to be using the CreateObject delegate because the code generating these dynamic methods is for a deserializer that should be able to handle any type (at least, primitives, structs, & class instances). However, I ran into a problem with the CreateObject delegate type so I decided to try the CreateRectangle delegate to debug things. I got a little closer to a working solution but something else isn’t right. What’s wrong with my code for both cases? That is, how can I make the dynamic method work for both CreateObject and CreateRectangle? Or, is my calling code the culprit?
Output:
{X=0,Y=0,Width=0,Height=0}
Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.
Exception has been thrown by the target of an invocation.
Common Language Runtime detected an invalid program.
Code:
using System;
using System.Drawing;
using System.Reflection.Emit;
namespace Experiments {
public class Program {
private delegate object CreateObject();
private delegate Rectangle CreateRectangle();
static void Main() {
Console.WriteLine(new Rectangle());
Console.WriteLine();
var dm = BuildDynamicMethod();
TryCreateDelegate<CreateObject>(dm);
Console.WriteLine();
TryCreateDelegate<CreateRectangle>(dm);
Console.WriteLine();
Console.ReadKey();
}
private static void TryCreateDelegate<T>(DynamicMethod dm) {
try {
var co = dm.CreateDelegate(typeof (T));
var value = co.DynamicInvoke(null);
Console.WriteLine(value);
} catch (Exception ex) {
Console.WriteLine(ex.Message);
var indent = 0;
while (ex.InnerException != null) {
indent++;
ex = ex.InnerException;
Console.WriteLine(new string('\t', indent) + ex.Message);
}
}
}
private static DynamicMethod BuildDynamicMethod() {
var tr = typeof(Rectangle);
var dm = new DynamicMethod("buildNewRectangle", tr, Type.EmptyTypes);
var il = dm.GetILGenerator();
il.Emit(OpCodes.Ldloca_S, (byte)0);
il.Emit(OpCodes.Initobj, tr);
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Box, tr);
il.Emit(OpCodes.Ret);
return dm;
}
}
}
1 Answer