Почему я не могу получить значение для параметров типа out или ref, используя Type.InvokeMember? - PullRequest
6 голосов
/ 27 марта 2012

Длинное название, но я хотел, чтобы оно было конкретным.Название действительно вопрос.Несмотря на то, что метод, который вызывает 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));

Ответы [ 3 ]

6 голосов
/ 24 сентября 2014

Я просто хотел помочь кому-то, кто борется (я справился) с неуправляемым (COM) и вернул ref-параметр. Таким образом, при использовании InvokeMember против COM-метода вы должны указать, какие аргументы относятся к типу ref. Это достигается с помощью ParameterModifier-class, например:

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;)

5 голосов
/ 27 марта 2012

В вашем втором фрагменте отсутствует довольно важная строка кода. Он должен выглядеть следующим образом, предполагая, что аргумент out имеет тип string:

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 [], который вы передаете, чтобы вы никогда не могли получить измененный аргумент.

3 голосов
/ 27 марта 2012

В вашем первом примере кода вызов InvokeMember не изменяет значение переменной parameter, он просто заменяет первый элемент в массиве параметров (который теперь указывает на другой экземпляр string),Поскольку вы не сохранили ссылку на этот массив, вы не можете получить значение выходного параметра.

Другими словами: массив изначально содержит копию переменной parameter (т.е. копиюссылки на пустую строку).После вызова parameter и значение в массиве ссылаются на 2 разных экземпляра строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...