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が正しく機能していません。リクエストオブジェクトの値を設定することはなく、常にnullのままになります

問題を解決し、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 に答える