如何将表达式访问限制为Roslyn中的外部类型



所以我通读了如何使用Roslyn计算表达式的方法,我想知道这是否可能,以及如何将表达式限制为一组基本的数学运算和对我提供的一组精简类型的运算(没有Console.Writeline、singletons、外部Dlls等(。如何强制和检查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

最新更新