2012-03-26 7 views
6

Długi tytuł, ale chciałem, aby był konkretny. Tytuł jest naprawdę pytaniem. Mimo że metoda wywołująca InvokeMember ma parametr out i przypisuje wartość temu parametrowi, nie mogę pobrać tej wartości. Oto kod Początkowo byłem przy użyciu:Dlaczego nie mogę pobrać wartości dla parametrów typu out lub ref używając Type.InvokeMember?

string parameter = ""; 
int result = Convert.ToInt32(typeof(Ability).InvokeMember(selectedMove, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new object[] { parameter })); 

Zmieniłem to ten, który teraz sprawia, że ​​działa prawidłowo, ale nie wiem dlaczego:

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

Odpowiedz

3

W pierwszym przykładzie kodowania, wywołanie InvokeMember nie modyfikuje wartości zmiennej parameter, po prostu zastępuje pierwszy element w tablicy parametrów (który teraz wskazuje na inną instancję string). Ponieważ nie zachowano odniesienia do tej tablicy, nie można pobrać wartości parametru wyjściowego.

Innymi słowy: tablica początkowo zawiera kopię zmiennej parameter (tj. Kopię odwołania do pustego ciągu znaków). Po wywołaniu parameter i wartość w tablicy odnoszą się do 2 różnych instancji ciągów.

5

W Twoim drugim fragmencie brakuje dość istotnej linii kodu. Powinno to wyglądać tak, zakładając się argument jest typu 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! 

Teraz powinien być również oczywiste, dlaczego 1-cia fragment nie może pracować, nie mają odniesienia do obiektu [] tablicy które przekazujesz, abyś nigdy nie mógł odzyskać zmodyfikowanego argumentu.

6

Po prostu chciałem pomóc komuś, kto zmaga się (ja) z niezarządzanym (COM) i odzyskiwaniem parametru ref. Tak więc, używając InvokeMember przeciwko COM-metoda, musisz powiedzieć, które argumenty są ref-type. Osiąga się to za pomocą ParameterModifier klasy, na przykład:

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

W kodzie powyżej, 3. argumentu jest ustawiana jako odniesienie (pMod [2] = true)

+0

wow ... to właśnie uratowałeś mi dzięki. –

Powiązane problemy