Pytanie Jak przekazać parametr jako odniesienie z MethodInfo.Invoke


Jak mogę przekazać parametr jako odniesienie MethodInfo.Invoke?

Jest to metoda, którą chcę wywołać:

private static bool test(string str, out byte[] byt)

Próbowałem tego, ale nie udało mi się:

byte[] rawAsm = new byte[]{};
MethodInfo _lf = asm.GetTypes()[0].GetMethod("test", BindingFlags.Static |  BindingFlags.NonPublic);
bool b = (bool)_lf.Invoke(null, new object[]
{
    "test",
    rawAsm
});

Zwrócone bajty są puste.


34
2018-01-08 17:45


pochodzenie




Odpowiedzi:


Najpierw musisz utworzyć tablicę argumentów i zachować odniesienie do niej. The out wartość parametru zostanie następnie zapisana w tablicy. Możesz więc użyć:

object[] arguments = new object[] { "test", null };
MethodInfo method = ...;
bool b = (bool) method.Invoke(null, arguments);
byte[] rawAsm = (byte[]) arguments[1];

Zwróć uwagę, że nie musisz podawać wartości dla drugiego argumentu, ponieważ jest to out parametr - wartość zostanie ustawiona za pomocą metody. Jeśli to byłby ref parametr (zamiast out) wtedy wartość początkowa byłaby użyta - ale wartość w tablicy nadal mogłaby zostać zastąpiona przez metodę.

Krótka, ale pełna próbka:

using System;
using System.Reflection;

class Test
{
    static void Main()
    {
        object[] arguments = new object[1];
        MethodInfo method = typeof(Test).GetMethod("SampleMethod");
        method.Invoke(null, arguments);
        Console.WriteLine(arguments[0]); // Prints Hello
    }

    public static void SampleMethod(out string text)
    {
        text = "Hello";
    }
}

47
2018-01-08 17:46





Kiedy metoda wywołana przez odbicie ma ref parametr zostanie skopiowany z powrotem do tablicy, która była używana jako lista argumentów. Aby uzyskać skopiowany odnośnik, wystarczy spojrzeć na tablicę używaną jako argumenty.

object[] args = new [] { "test", rawAsm };
bool b = (bool)_lf.Invoke(null, args);

Po tym wezwaniu args[1] będzie mieć nowe byte[] 


11
2018-01-08 17:48