c# - 如何限制表达式访问 Roslyn 中的外部类型?

标签 c# .net expression roslyn side-effects

所以我通读了如何evaluate expressions的方法与 Roslyn 一起,我想知道是否有可能以及如何将表达式限制为一组基本数学运算和对我提供的一组精简类型的运算(无 Console.Writeline、单例、外部 Dll 等)。如何强制和检查 Roslyn 表达式的这种表达式能力降低?

最佳答案

一种可能的解决方案是将代码作为表达式求值并分析表达式,例如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://learn.microsoft.com/en-us/dotnet/csharp/expression-trees-interpreting

关于c# - 如何限制表达式访问 Roslyn 中的外部类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60664034/

相关文章:

.net - 秒表真的坏了吗?

Haskell Let 表达式求值

c# - 使用 Graphics.DrawImage() 绘制带透明度/Alpha channel 的图像

c# - 解析标记扩展时遇到类型 'Converter' 的未知属性 'MS.Internal.Markup.MarkupExtensionParser+UnknownMarkupExtension'

.net - 拉伸(stretch)控件以填充 ItemsControl

algorithm - 用函数解析表达式

java - 为什么表达式 `(true) ? null: null` 被视为 char[]

c# - 当 id 具有文件扩展名时,ASP.NET MVC 4 路由不起作用

c# - 如何在匹配字符串之前找到一个词

c# - 不能通过并发线程访问破坏数据