理想情况下,我想使用CreateObject
委托,因为生成这些动态方法的代码用于反序列化程序,该序列化程序应能够处理任何类型(至少是基元,结构和类实例)。但是,我遇到了CreateObject
委托类型的问题,因此我决定尝试使用CreateRectangle
委托调试内容。我更接近可行的解决方案,但其他方法不正确。两种情况下我的代码有什么问题?也就是说,如何使动态方法对CreateObject
和CreateRectangle
都起作用?还是我的通话代码是罪魁祸首?
输出:
{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.
码:
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;
}
}
}
最佳答案
private delegate object CreateObject();
private delegate Rectangle CreateRectangle();
static void Main()
{
Console.WriteLine(new Rectangle());
Console.WriteLine();
TryCreateDelegate<CreateObject>(BuildDynamicMethod_Boxed());
Console.WriteLine();
TryCreateDelegate<CreateRectangle>(BuildDynamicMethod());
Console.WriteLine();
}
private static DynamicMethod BuildDynamicMethod_Boxed()
{
var TRect = typeof(Rectangle);
var dm = new DynamicMethod("buildNewRectangle", typeof(object), Type.EmptyTypes);
var il = dm.GetILGenerator();
il.Emit(OpCodes.Ldloca_S, il.DeclareLocal(TRect));
il.Emit(OpCodes.Initobj, TRect);
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Box, TRect);
il.Emit(OpCodes.Ret);
return dm;
}
private static DynamicMethod BuildDynamicMethod()
{
var TRect = typeof(Rectangle);
var dm = new DynamicMethod("buildNewRectangle", TRect, Type.EmptyTypes);
var il = dm.GetILGenerator();
il.Emit(OpCodes.Ldloca_S, il.DeclareLocal(TRect));
il.Emit(OpCodes.Initobj, TRect);
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ret);
return dm;
}
private static void TryCreateDelegate<T>(DynamicMethod dm)
{
try
{
var co = dm.CreateDelegate(typeof(T));
var value = co.DynamicInvoke();
}
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);
}
}
}