如何在System.ServiceModel.ClientBase<>的ChannelBase<> EndInvoke中使用out参数
解决反射调用带out参数方法的问题
我来帮你搞定这个反射调用里out参数的问题~你的核心需求是不修改原方法bool GetInfo(out List<foo> bar);,通过EndInvoke正确获取out参数返回的List,同时拿到bool返回值对吧?
之前的尝试之所以失败,是因为没搞清楚反射里处理out/ref参数的逻辑:out参数是引用传递,你需要在参数数组里给它留一个位置,方法执行后会把结果写入这个数组的对应索引,而不是直接在数组初始化里写out bar(这是语法错误)。
正确的调用步骤
- 先声明out对应的变量(不需要提前初始化,符合out的规则)
- 创建参数数组,把这个变量放进去(数组会作为容器承载方法修改后的值)
- 调用
EndInvoke时传入这个数组,同时接收方法的bool返回值 - 调用完成后,原变量或者数组对应位置就会被赋值为方法返回的List
完整代码示例
// 声明out参数对应的变量,无需初始化 List<foo> bar = null; // 创建参数数组,把变量放入(out是引用传递,数组会保存方法修改后的值) object[] invokeArgs = new object[] { bar }; // 执行EndInvoke,传入参数数组,并接收bool返回值 bool operationSuccess = (bool)yourAsyncResult.EndInvoke(invokeArgs); // 现在bar已经被方法赋值了,也可以从数组里取 bar = (List<foo>)invokeArgs[0];
为什么之前的尝试不行?
- 直接写
new object[] { out bar }:C#语法不允许在数组初始化器里使用out关键字,编译都通不过 - 传
bar/空数组/null:方法找不到对应的out参数位置,会抛出参数不匹配的异常 - 把
EndInvoke的返回值强转为List<foo>:GetInfo的返回值是bool,List是通过out参数输出的,强转必然失败
这样调用就能在不修改原方法的前提下,同时拿到bool返回值和out参数的List啦~
内容的提问来源于stack exchange,提问作者besplash
相关产品推荐
相关产品推荐

