У меня есть следующее lambda
, которое отлично работает:
public interface IOhlcv : ITick
{
decimal Open { get; set; }
decimal High { get; set; }
decimal Low { get; set; }
decimal Close { get; set; }
decimal Volume { get; set; }
}
c1,c2,c3
имеют тип IList<IOhlcv>
Это lambda
:
(c1, c2, c3) => c1.Close / c2.Close * c3.Close
Если lambda
было string
представлением lambda
,
string lambdaStr = "(c1, c2, c3) => c1.Close / c2.Close * c3.Close"
как мне compile
реально lambda
? ПРИМЕЧАНИЕ: (lambdaStr может быть создан динамически, например, c1, c2, c3 может быть любым количеством параметров с операторами между ними)
Я пытался использовать https://github.com/dotnet/roslyn/wiki/Scripting-API-Samples#expr
Вот так:
var options = ScriptOptions.Default.AddReferences(typeof(IOhlcv).Assembly);
var projection = await CSharpScript.EvaluateAsync<IList<decimal>>(projectionString, options);
но я не могу заставить его работать:
Message = "(1,1): error CS1660: Cannot convert lambda expression to type 'IList<decimal>' because it is not a delegate type"
Редактировать 1
Даже пытаясь это
try
{
string lambdaStr = "(c1, c2, c3) => c1.Close / c2.Close * c3.Close";
var options = ScriptOptions.Default.AddReferences(typeof(IOhlcv).Assembly);
// this will be a delegate type and you will need to turn it into one that fits
dynamic projection = await CSharpScript.EvaluateAsync<dynamic>(lambdaStr, options);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
дай это exception
:
'Microsoft.CodeAnalysis.Scripting.CompilationErrorException' in Microsoft.CodeAnalysis.Scripting.dll
Microsoft.CodeAnalysis.Scripting.CompilationErrorException: (1,1): error CS1660: Cannot convert lambda expression to type 'object' because it is not a delegate type
at Microsoft.CodeAnalysis.Scripting.ScriptBuilder.ThrowIfAnyCompilationErrors(DiagnosticBag diagnostics, DiagnosticFormatter formatter)
at Microsoft.CodeAnalysis.Scripting.ScriptBuilder.CreateExecutor[T](ScriptCompiler compiler, Compilation compilation, Boolean emitDebugInformation, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Scripting.Script`1.GetExecutor(CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Scripting.Script`1.RunAsync(Object globals, Func`2 catchException, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.RunAsync[T](String code, ScriptOptions options, Object globals, Type globalsType, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.EvaluateAsync[T](String code, ScriptOptions options, Object globals, Type globalsType, CancellationToken cancellationToken)
at Trady.Form1.<ZipSeries>d__17.MoveNext() in C:\Users\idf\Form1.cs:line 281
Редактировать 2
Такое предположение кажется, что что-то приближается, но без сигары
try
{
var options = ScriptOptions.Default.AddReferences(typeof(IOhlcv).Assembly);
var projection = await CSharpScript.EvaluateAsync<Func<IOhlcv,IOhlcv,IOhlcv,decimal>>(projectionString, options);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
ex = {"(1,18): error CS1061: 'IOhlcv' does not contain a definition for 'close' and no accessible extension method 'close' accepting a first argument of type 'IOhlcv' could be found (are you missing a using directive or an assembly reference?)"}
Редактировать 3
Произошла ошибка в коде, когда генерировался ".close". Когда он изменяется на «.Close», код в Edit 2 работает.
Это все еще не отвечает на вопрос о том, как создать lambda
, который может занять variable number of parameters
, поскольку Func<IOhlcv,IOhlcv,IOhlcv,decimal>
является аппаратным, но это шаг вперед.
Может ли CSharpScript.EvaluateAsync
скомпилироваться в delegate
, который принимает переменное число параметров?