Немного предыстории - я пишу взаимодействие между 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;
}
}
Когда я делаю это, я получаю следующее исключение: Невозможно привязать к целевому методу, потому что его Прозрачность подписи или безопасности не совместима с типом делегата.
Мой вопрос: я на правильном пути? Я также возился с использованием лямбды, но с этим подходом ушел еще меньше.