Как ограничить доступ выражений для внешних типов в Roslyn? - PullRequest
2 голосов
/ 13 марта 2020

Итак, я прочитал, как оценивать выражения с Рослином, и мне интересно, возможно ли это и как ограничить выражение набором базовых c математических операций и операций на сокращенном наборе типов, предоставленных мной (без Console.Writeline, синглтоны, внешние Dlls et c). Как заставить и проверить такое сокращение возможностей выражений для выражений Roslyn?

1 Ответ

3 голосов
/ 15 марта 2020

Одним из возможных решений является оценка кода как выражения и анализ выражения, например 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);
    }
}

In всего:

// 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

...