Преобразование функции variadi c в System.Action с использованием Delegate.CreateDelegate - PullRequest
0 голосов
/ 04 февраля 2020

Немного предыстории - я пишу взаимодействие между C# и другим языком программирования и мне нужно преобразовать представление функции из одного в другое. скажем ради этого обсуждения, что язык называется Taco

Теперь - у меня есть ситуация, когда мне нужно сгенерировать System.Action<object, object, ...> (каждый аргумент шаблона является объектом, потому что другой язык динамически типизирован). Я знаю длину во время выполнения.

Вот что я пытаюсь:

    internal class VariadicAction
    {
        private TacoFuncPtr FuncPtr { get; set; }

        internal VariadicAction(TacoFuncPtr ptr)
        {
            FuncPtr = ptr;
        }

        internal void Run(params object[] varArgs)
        {
            //convert each item in varArgs to taco objects
            //call FuncPtr with them.
            var numArgs = varArgs.Length;
            var tacoArgs = new TacoArgs[numArgs];
            //convert varArgs to taco
            var tacoResult = FuncPtr.Invoke(tacoArgs);
        }
    }

    //converts Taco functions to C# Action so that they can be passed to C# functions which take a
    //System.Action as an argument.  Clients call it by passing in a System.Action with the right 
    //number of generic parameters
    class TacoFunctionConverter
    {
        static bool TryConvertTacoFunctionToCSharp<T>(TacoObject tacoFunctor, out T value)
        {
            value = default(T)
            var tT = typoeof(T);
            //lets say this returns the number of arguments from C#, requires it to be a System.Action
            var numArgs = GetNumArgs(tT);
            if (GetNumArgs(tacoFunctor) != numArgs) return false;

            var variadcAction = new VariadicAction(tacoFunctor);
            //construct a System.Action<object,...> variadically!
            var genericActionType = typeof(Action<>);
            Type[] types = Enumerable.Repeat(typeof(object), numArgs).ToArray();
            var constructedActionType = genericActionType.MakeGenericType(types);
            Delegate del = Delegate.CreateDelegate(constructedActionType, variadicAction, "Run", false);
            actionObj = (object)del;
            value = (T)actionObj;
            return true;
        }
    }

Когда я делаю это, я получаю следующее исключение: Невозможно привязать к целевому методу, потому что его Прозрачность подписи или безопасности не совместима с типом делегата.

Мой вопрос: я на правильном пути? Я также возился с использованием лямбды, но с этим подходом ушел еще меньше.

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