一个很长的标题,但我希望它是特定的。标题确实是个问题。即使InvokeMember
调用的方法有一个out
参数,并为该参数赋值,我也无法获取该值。这是我最初使用的代码:
string parameter = "";
int result = Convert.ToInt32(typeof(Ability).InvokeMember(selectedMove, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new object[] { parameter }));
我把它改成了这个,现在它可以按预期工作了,但我不知道为什么:
object[] args = new object[1]; //necessary to retrieve ref/out parameter
int result = Convert.ToInt32(typeof(Ability).InvokeMember(selectedMove, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, args));
我只是想帮助那些在非托管(COM)和取回ref参数方面遇到困难的人。因此,当对COM方法使用InvokeMember时,必须判断哪些参数是ref类型。这是通过使用ParameterModifier类来实现的,例如:
object[] args = new object[3] { param1, param2, errorStr };
ParameterModifier pMod = new ParameterModifier(3);
pMod[2] = true;
ParameterModifier[] mods = { pMod };
object tempObj = myCOMObject.GetType().InvokeMember("MyCOMMethod", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Public, null, myCOMObject, args, mods, null, null);
在上面的代码中,第三个参数被设置为引用(pMod[2]=true;)
您的第二个片段缺少一行相当重要的代码。它应该是这样的,假设out参数的类型是字符串:
object[] args = new object[1]; //necessary to retrieve ref/out parameter
int result = Convert.ToInt32(typeof(Ability).InvokeMember(selectedMove,
BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static,
null, null, args));
string outValue = (string)args[0]; // <=== here!
现在应该也很清楚为什么你的第一个代码段不能工作了,你没有对你传递的object[]数组的引用,所以你永远无法检索修改后的参数。
在第一个代码示例中,对InvokeMember
的调用不会修改parameter
变量的值,它只是替换参数数组中的第一个项(现在它指向不同的string
实例)。由于没有保留对此数组的引用,因此无法检索输出参数的值。
换句话说:数组最初包含parameter
变量的副本(即对空字符串的引用的副本)。调用之后,parameter
和数组中的值引用了2个不同的字符串实例。