Я работаю над небольшим языком программирования для Microsoft DLR, и у меня возникла небольшая проблема с вызовом моих анонимных методов. В частности, код:
Delegate CompiledBody = Expression.Lambda(rt.Parser.ParseSingle(Body), parms).Compile();
Итак, parms - это массив, содержащий одно выражение ParameterExpression, а первый аргумент содержит соответствующие выражения для определения анонимной функции. Когда я пытаюсь вызвать моего делегата с помощью Expression.Call для CompiledBody.Method (MethodInfo), я получаю сообщение об ошибке:
Unhandled Exception: System.ArgumentException: Expression of type 'System.Object'
cannot be used for parameter of type 'System.Runtime.CompilerServices.Closure'
of method 'Shiro.Runtime.ShiroAtom lambda_method(System.Runtime.CompilerServices
.Closure, Shiro.Runtime.ShiroAtom)'
Теперь где-то по пути мой метод с одним аргументом получил второй аргумент, типа System.Runtime.CompilerServices.Closure (второй параметр типа ShiroAtom - мой параметр). Это имеет смысл, за исключением того, что (а) мне действительно все равно, находится ли метод в этом контексте в области действия Closure, и (b) я не могу создать даже пустую область действия Closure для передачи этого параметра.
Буду признателен за любую помощь! Заранее спасибо.
РЕДАКТИРОВАТЬ: Некоторая дополнительная информация, основанная на удивительном ответе ниже:
Где этот код происходит глубоко в недрах моего парсера. У меня есть поток токенов (на самом деле, атомы), которые переводятся в AST. Этот конкретный бит является процедурой анализа вызова функции. Он создал CompiledBody, затем пытается вызвать его, используя что-то вроде:
return Expression.Call(CompiledBody.Method, Expression.Constant("argument"));
Результирующая лямбда представляет функцию. Исходя из моей архитектуры, есть только несколько мест, которые я могу вызвать DynamicInvoke или просто вызвать скомпилированный делегат, и это не одно из них. Хотелось бы привести более существенный пример, но эта ситуация возникает в разгар парсера с ручным кодированием, и потребовалось бы слишком много кода, чтобы действительно сообщить почему ситуация такова, но я действительно нужен способ вызова скомпилированной лямбды через Expression.Call, как показано выше.
Суть проблемы в том, что моей скомпилированной лямбде требуется 1 дополнительный параметр к указанным мною, CompilerServices.Closure, и я не знаю, как его создать.