代码之家  ›  专栏  ›  技术社区  ›  Ivan

将lambda的字符串表示形式编译为lambda

  •  0
  • Ivan  · 技术社区  · 7 年前

    我有以下几点 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>

    这是 拉姆达 :

    (c1, c2, c3) => c1.Close / c2.Close * c3.Close
    

    如果 拉姆达 是一个 string 代表 拉姆达 ,

    string lambdaStr = "(c1, c2, c3) => c1.Close / c2.Close * c3.Close"
    

    我该怎么办 compile 这是一场真正的战争 拉姆达 ? 注:(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”的代码中存在错误。当代码中的“关闭”被更改时 编辑2 作品

    它仍然没有回答如何创建一个 拉姆达 这可能需要一段时间 variable number of parameters 自从 Func<IOhlcv,IOhlcv,IOhlcv,decimal> 是硬连线的,但这是向前迈出的一步。

    可以 CSharpScript.EvaluateAsync 编译成 delegate 需要可变数量的参数吗?

    1 回复  |  直到 7 年前
        1
  •  0
  •   Maximilian Burszley    7 年前

    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);
    
    // or similar
    System.Console.WriteLine(projection(a, b, c));