0
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);
4

1 回答 1

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);
    }
}

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

于 2011-07-10T18:07:52.563 回答