2008-11-12 74 views
0

我正在构建一个库,以简化C#中的后期绑定调用,并且遇到了引用参数问题。我有以下方法添加的方法中使用的参数调用如何修改方法内的盒装值类型

public IInvoker AddParameter(ref object value) 
    { 
     //List<object> _parameters = new List<object>(); 
     _parameters.Add(value);   

     //List<bool> _isRef = new List<bool>(); 
     _isRef.Add(true); 

     return this; 
    } 

这还不值类型的工作,因为他们得到装箱为对象,因此它们不会被修改。例如:

int param1 = 2; 
object paramObj = param1; 
//MulFiveRef method multiplies the integer passed as a reference parameter by 5: 
//void MulFiveRef(ref int value) { value *= 5; } 
fi.Method("MulFiveRef").AddParameter(ref paramObj); 

这是行不通的。后期绑定调用是成功的,并且包含参数(_parameters)的内部List确实被修改,但不是调用之外的值。

有没有人知道一个简单的方法来克服这个限制? 无法修改AddParameter签名,因为对于后期绑定调用,您无法事先知道参数的类型(以及在拨打电话之前插入对象数组内的呼叫的所有参数的方法)

提前致谢。

回答

1

如果该值改变方法里面,你需要声明一个临时(object)变量传递(ref)的方法,事后自己拆箱它:

int i = 3; 
    //... 
    object obj = i; 
    Foo(ref obj); 
    i = (int)obj; 

注意这将不允许您在事件发生后更新值。事件或回调可能是将更改传回给调用者的另一种方式。也

需要注意的是C#4.0有一些技巧,以帮助这个在COM呼叫的上下文中(其中ref object是如此普遍,[当然dynamic加上后期绑定,作为乔恩指出])。

1

无论如何,你的方法并没有改变value - 你为什么通过引用传递它?这可能是有道理的,但对我来说并不是很清楚。请注意,您提供的示例代码无论如何都不会编译,因为参数ref必须是,与的参数完全相同。 (另外,您是否知道C#4.0和.NET 4.0将对后期绑定提供内置支持?有可能语言集成的版本比仅有库的版本更易于使用。肯定这是值得花时间在图书馆在这个时间点?)

编辑:你提供的代码真的不会编译。你不会为ref参数装箱,因为参数和参数类型必须完全相同。下面是一些示例代码,以证明这一点:

public class Test 
{ 
    static void Main() 
    { 
     int i; 
     Foo(ref i); // Won't compile - error CS1502/1503 
    } 

    static void Foo(ref object x) 
    { 
    } 
} 

如果您当前的代码编译,那么这不是你的问题给出的代码。也许你有另一个AddParameter超载,它接受ref int

+0

我道歉,你是对的。我贴的originaly代码不能编译。 – 2008-11-12 10:55:15

0

好,感谢乔恩斯基特改正,马克Gravell代码,我想出了这个接口:

 //This will be created with a factory 
     IOperationInvoker invoker = new OperationInvoker(Activator.CreateInstance<MyLateBindingTestType>()); 

     int param1 = 2; 
     object paramObj = param1; 

     invoker.AddParameter(ref paramObj).Invoke("MulFiveRef"); 

     param1 = (int)invoker.Parameters[0]; 

并不完全如我想象的,但仅仅是方式更可读,我以前的接口:

 IOperationInvoker invoker = new OperationInvoker(Activator.CreateInstance<MyLateBindingTestType>()); 
     int refValue = 10; 
     object[] args = Args.Build(refValue); 

     invoker.Call("MulFiveRef", Args.ByRefIndexs(0), args); 

     refValue = (int)args[0]; 

非常感谢你的帮助的人:)