您的位置:首页 > 其它

利用反射调用方法时,处理ref,out参数需要注意的问题

2015-03-18 12:31 411 查看
项目中如下的泛型方法,因为要在运行时,动态指定类型参数,所以要利用反射来实现。

public static TR Deserialize<TR>(byte[] source, ref int offset)

一般做法如下:



// 变量 type是该方法所在类型的运行时Type
// model是已经定义的实例
MethodInfo genericMethod = type.GetMethod("Deserialize", BindingFlags.Public | BindingFlags.Static);
MethodInfo mi = genericMethod.MakeGenericMethod(model.GetType());

反射拿到MethodInfo之后,即可调用方法

// int p
// byte[] source
// object result
result = mi.Invoke(null, new object[]{source, p});

注意这里的调用方法传的参数,形参offset并没有像直接调用方法那样指定ref修饰符,像refout这样的参数修饰符在利用反射调用方法时是不需要指定的。

回到我们的主题,我们希望方法调用之后,我们传的参数p的值被修改了,事实上,我们会发现,参数p的值并未被改变。

MSDN上面,.net
framework 4.5版本中,特别提到了这一点,refout参数可能被修改。那我们的问题出在哪里了呢?

问题出在了我们传参数的过程。上面的方法调用,参数被装入数组,由Invoke方法传递给mi指向的方法。我们构造object数组的初始化过程,是值传递的。另一方面,这个object数组在调用完成后,就被丢掉了。将上述代码改成如下写法:

object[] args = new object[]{source, p};
result = mi.Invoke(null, args);
p = (int)args[1];

然后,我们就会发现,被修改的参数,其实在参数数组中好好的放着呢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐