【问题标题】:How to limit expression access to types external in Roslyn?如何限制对 Roslyn 中外部类型的表达式访问?
【发布时间】:2020-06-25 02:09:41
【问题描述】:

所以我阅读了如何使用 Roslyn evaluate expressions 的方法,我想知道这是否可能以及如何将表达式限制为一组基本的数学运算和对我提供的一组减少的类型的运算(没有控制台.Writeline、单例、外部 Dll 等)。如何强制和检查 Roslyn 表达式的这种表达能力减少?

【问题讨论】:

    标签: c# .net expression roslyn side-effects


    【解决方案1】:

    一种可能的解决方案是将代码评估为表达式并分析表达式,例如Expression<Func<Album, bool>>.

    Expression<Func<Album, bool>> discountFilterExpression = await CSharpScript.EvaluateAsync<Expression<Func<Album, bool>>>(discountFilter, options);
    

    然后使用ExpressionVisitor 访问表达式的节点并检查表达式是否仅包含有效/允许的节点和类型。

    例如,下面的访问者检查Math是否在评估的代码中被使用,如果是,则将表达式设置为无效:

    class NoMathExpressionVisitor : ExpressionVisitor
    {
        public bool IsValid { get; private set; } = true;
    
        protected override Expression VisitMethodCall(MethodCallExpression node)
        {
            if (node.Method.DeclaringType == typeof(Math))
            {
                IsValid = false;
            }
    
            return base.VisitMethodCall(node);
        }
    }
    

    总共:

    // Generate expression
    Expression<Func<Album, bool>> discountFilterExpression = await CSharpScript.EvaluateAsync<Expression<Func<Album, bool>>>(discountFilter, options);
    
    // Visit each node using NoMathExpressionVisitor
    var expressionVisitor = new NoMathExpressionVisitor();
    expressionVisitor.Visit(discountFilterExpression);
    
    // Check result
    // For code: a => Math.Abs(a.Quality) > 10, IsValid returns false
    if (expressionVisitor.IsValid)
    {
        // If the expression is valid, compile the expression to
        // Func<> and run.
        var result = discountFilterExpression.Compile()(album);
    }
    

    https://docs.microsoft.com/en-us/dotnet/csharp/expression-trees-interpreting

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多