2010-06-20 15 views
2

J'ai besoin d'appeler une méthode avec des arguments ref via un RealProxy. J'ai isolé le problème au code suivant:Argument de référence via un RealProxy

using System; 
using System.Reflection; 
using System.Runtime.Remoting.Messaging; 
using System.Runtime.Remoting.Proxies; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      HelloClass hello=new HelloClass(); 
      TestProxy proxy = new TestProxy(hello); 
      HelloClass hello2 = proxy.GetTransparentProxy() as HelloClass; 

      string t = ""; 
      hello2.SayHello(ref t); 
      Console.Out.WriteLine(t); 
     } 
    } 

    public class TestProxy : RealProxy 
    { 
     HelloClass _hello; 

     public TestProxy(HelloClass hello) 
      : base(typeof(HelloClass)) 
     { 
      this._hello = hello; 
     } 

     public override System.Runtime.Remoting.Messaging.IMessage Invoke(System.Runtime.Remoting.Messaging.IMessage msg) 
     { 
      IMethodCallMessage call = msg as IMethodCallMessage; 
      object returnValue = typeof(HelloClass).InvokeMember(call.MethodName, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, _hello, call.Args); 
      return new ReturnMessage(returnValue, null, 0, call.LogicalCallContext, call); 
     } 
    } 

    public class HelloClass : MarshalByRefObject 
    { 
     public void SayHello(ref string s) 
     { 
      s = "Hello World!"; 
     } 
    } 
} 

Le programme devrait produire le "Hello World!" sortie, mais en quelque sorte la modification des arguments ref se perd dans le proxy. Que dois-je faire pour que cela fonctionne?

Répondre

7

Le deuxième paramètre de ReturnMessage doit contenir les valeurs des paramètres ref et out à renvoyer. Vous pouvez les obtenir en sauvegardant une référence au tableau que vous avez passé:

public override System.Runtime.Remoting.Messaging.IMessage Invoke(System.Runtime.Remoting.Messaging.IMessage msg) 
{ 
    IMethodCallMessage call = msg as IMethodCallMessage; 
    var args = call.Args; 
    object returnValue = typeof(HelloClass).InvokeMember(call.MethodName, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, _hello, args); 
    return new ReturnMessage(returnValue, args, args.Length, call.LogicalCallContext, call); 
} 
+0

Merci beaucoup! C'était extrêmement utile. – Guge

+0

Merci, ça a marché comme un charme – phuongnd