什么相当于Reflection.Emit IL中的代码

时间:2011-07-10 17:48:36

标签: .net reflection cil reflection.emit il

void DoSomething(Data data){
    var myDataRequest = new DataRequest();
    myDataRequest.ID = data.ID
}

我有以下

 methodIL.Emit(OpCodes.Ldloc_1);
 methodIL.Emit(OpCodes.Ldarg_0);
 methodIL.Emit(OpCodes.Callvirt, getMethodForData);
 methodIL.Emit(OpCodes.Callvirt, setMethodForDataRequest);
 methodIL.Emit(OpCodes.Nop);

但它似乎不起作用

代码,我真的想生成:

static Response TestRequestResponse(RequestData requestData) {
            var wrapper = new WrapperResponse<Response>();
            var request = new Request() { };
            request.RequestID = requestData.RequestID;
            request.Value = requestData.Value;
            request.ID = requestData.ID;
            request.OnReply(wrapper.Handle);
            request.WaitForResponse(true);
            request.TimeOut(TimeSpan.FromSeconds(30));
            request.Send();
            return wrapper.Response;
        }

我在这里有以下代码:http://pservicebusext.codeplex.com/SourceControl/changeset/view/4f8a4f1190ae#PServiceBus.RemoteProxy%2fPServiceBus.RemoteProxy%2fESBProxy.cs

有一个名为CreateProxy()的方法,它假设生成上面的代码。但是部分循环并生成方法的get和set不能正常工作。它从不设置请求对象的值,它始终保留为空

我解决了这个问题,我从使用OpCodes.Ldarg_0变为OpCodes.Ldarg_1

methodIL.Emit(OpCodes.Ldloc_1);
 methodIL.Emit(OpCodes.Ldarg_1);
 methodIL.Emit(OpCodes.Callvirt, getMethodForData);
 methodIL.Emit(OpCodes.Callvirt, setMethodForDataRequest);
 methodIL.Emit(OpCodes.Nop);

1 个答案:

答案 0 :(得分:2)

简单,编译你的方法并使用一些反编译器(Reflector甚至LINQPad)来读取IL。我得到了以下IL:

IL_0000:  newobj      DataRequest..ctor
IL_0005:  stloc.0     
IL_0006:  ldloc.0     
IL_0007:  ldarg.1     
IL_0008:  callvirt    Data.get_ID
IL_000D:  callvirt    DataRequest.set_ID
IL_0012:  ret

编辑:以下代码适用于我:

public class DataRequest
{
    public DataRequest()
    {}

    private int m_id;
    public int ID
    {
        get { return m_id; }
        set { m_id = value; }
    }
}

public class Data
{
    private int m_id;
    public int ID
    {
        get { return m_id; }
        set { m_id = value; }
    }
}

class Program
{
    static void Main()
    {
        var method = new DynamicMethod("DoSomething", typeof(void), new[] { typeof(Data) });
        var methodIL = method.GetILGenerator();
        var constructor = typeof(DataRequest).GetConstructor(new Type[0]);
        var getMethodForData = typeof(Data).GetProperty("ID").GetGetMethod();
        var setMethodForDataRequest = typeof(DataRequest).GetProperty("ID").GetSetMethod();
        methodIL.Emit(OpCodes.Newobj, constructor);
        // storing and loading the same object to the some local is useless
        //var dataReuqest = methodIL.DeclareLocal(typeof(DataRequest));
        //methodIL.Emit(OpCodes.Stloc, dataReuqest.LocalIndex);
        //methodIL.Emit(OpCodes.Ldloc, dataReuqest.LocalIndex);
        methodIL.Emit(OpCodes.Ldarg_0);
        methodIL.Emit(OpCodes.Callvirt, getMethodForData);
        methodIL.Emit(OpCodes.Callvirt, setMethodForDataRequest);
        methodIL.Emit(OpCodes.Ret);
        var f = (Action<Data>)method.CreateDelegate(typeof(Action<Data>));
        var data = new Data { ID = 42 };
        f(data);
    }
}

也许您忘了声明您正在使用的局部变量?