вызов метода через отражение, которое принимает действие <T>.Все методы, содержащие класс и T помечены как внутренние - PullRequest
0 голосов
/ 12 ноября 2018

У меня есть такой внутренний метод

void Foo(Action<DB> act)

класс DB находится в той же сборке и также помечен как внутренний.Я могу понять, как получить methodinfo для Foo, но я не могу понять, как настроить обратный вызов act в вызывающем коде.Это то, что я имею до сих пор (как добавленная специя, я хочу вызвать другой внутренний метод изнутри обратного вызова)

    var tt = eng.GetType().Assembly;
    var dd = tt.GetType("Internal.DB");
    var kk = typeof(Action<>);
    Type[] targs =  { dd };
    var qq = kk.MakeGenericType(targs);
    MethodInfo dynMethod = eng.GetType().GetMethod("Foo", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { qq },null);
    dynMethod.Invoke(this, new object[] {
        ((Action<object>)(db=>{
       MethodInfo dynMethod2 = db.GetType().GetMethod("Wiz", BindingFlags.NonPublic | BindingFlags.Instance);
        dynMethod2.Invoke(db);
    })) }); 

моя проблема здесь (я думаю)

((Action<object>)(db=>{

Мне действительно нужно

((Action<DB>)(db=>{

, но я не могу этого сделать (БД внутренняя), тот, в котором object компилируется, но не выполняется во время выполнения, говоря, что объект имеет неправильный тип.

Ответы [ 2 ]

0 голосов
/ 12 ноября 2018

Немного сложно понять, что именно вы пытаетесь сделать, но если Wiz - это метод БД, который не принимает никаких параметров, то я считаю, что вам нужно что-то вроде этого:

dynMethod.Invoke(this, new object[] {
    ((Action<DB>)(db=> {
        MethodInfo dynMethod2 = db.GetType().GetMethod("Wiz", BindingFlags.NonPublic | BindingFlags.Instance);
        dynMethod2.Invoke(db, null);
})) });
0 голосов
/ 12 ноября 2018

Я очень мало изменил ваш пример и получил код, который компилируется и выполняется до конца.Есть ли вероятность, что ваш DB.Wiz () выдает исключение?Если нет, нам может потребоваться дополнительная информация о том, какая среда выполнения дает вам эту проблему, или более полный пример.Ниже приведен пример правильного вывода "Hello, World!"

.Net 4.6.1 Решение

Проект ConsoleApp, имеющий ссылку на пространство имен библиотеки классов Internal.Я изменил ваш dynMethod2.Invoke() для передачи пустого объекта [], так как ваш пример не компилировался с одним параметром в Invoke.Также убраны лишние скобки вокруг лямбда-выражения.

private static void Main(string[] args)
{
    Internal.Eng eng = new Internal.Eng();

    var tt = eng.GetType().Assembly;
    var dd = tt.GetType("Internal.DB");
    var kk = typeof(Action<>);
    Type[] targs = { dd };

    var qq = kk.MakeGenericType(targs);

    MethodInfo dynMethod = eng.GetType().GetMethod("Foo", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { qq }, null);

    dynMethod.Invoke(eng, new object[] {
        (Action<object>)(db=>{
            MethodInfo dynMethod2 = db.GetType().GetMethod("Wiz", BindingFlags.NonPublic | BindingFlags.Instance);
            dynMethod2.Invoke(db, new object[]{ });
        })
    });
}

Библиотека классов Internal пространство имен.

using System;

namespace Internal
{
    public class Eng
    {
        internal void Foo(Action<DB> act) => act(new DB());
    }

    internal class DB
    {
        internal void Wiz()
        {
            Console.WriteLine("Hello, World!");
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...