所以我通读了如何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/