C# 如何为未选中语句创建表达式树语句

C# 如何为未选中语句创建表达式树语句,c#,code-generation,C#,Code Generation,在我的表达式树(使用表达式类创建)中,我需要将代码包装在未选中的块()中,但如何包装?表达式类型没有什么有趣的内容。表达式类型有单独版本的每个运算符,用于选中和未选中的操作。要将表达式主体中的任何选中的操作更改为未选中的操作,您不能将整个操作包装在未选中的表达式中。您需要遍历整个表达式树,找到选中操作的所有用法,并用这些操作的未选中版本替换它们 public static Expression MakeUnchecked(this Expression expression) { ret

在我的表达式树(使用
表达式
类创建)中,我需要将代码包装在未选中的块()中,但如何包装?
表达式
类型没有什么有趣的内容。

表达式
类型有单独版本的每个运算符,用于选中和未选中的操作。要将表达式主体中的任何
选中的
操作更改为
未选中的
操作,您不能将整个操作包装在
未选中的
表达式中。您需要遍历整个表达式树,找到选中操作的所有用法,并用这些操作的未选中版本替换它们

public static Expression MakeUnchecked(this Expression expression)
{
    return new UncheckedExpressionVisitor().Visit(expression);
}

public class UncheckedExpressionVisitor : ExpressionVisitor
{
    protected override Expression VisitBinary(BinaryExpression node)
    {
        switch (node.NodeType)
        {
            case ExpressionType.AddAssignChecked:
                return base.Visit(Expression.AddAssign(node.Left, node.Right));
            case ExpressionType.AddChecked:
                return base.Visit(Expression.Add(node.Left, node.Right));
            case ExpressionType.MultiplyAssignChecked:
                return base.Visit(Expression.MultiplyAssign(node.Left, node.Right));
            case ExpressionType.MultiplyChecked:
                return base.Visit(Expression.Multiply(node.Left, node.Right));
            case ExpressionType.SubtractAssignChecked:
                return base.Visit(Expression.SubtractAssign(node.Left, node.Right));
            case ExpressionType.SubtractChecked:
                return base.Visit(Expression.Subtract(node.Left, node.Right));
            default:
                return base.VisitBinary(node);
        }
    }

    protected override Expression VisitUnary(UnaryExpression node)
    {
        switch (node.NodeType)
        {
            case ExpressionType.ConvertChecked:
                return base.Visit(Expression.Convert(node.Operand, node.Type));
            case ExpressionType.NegateChecked:
                return base.Visit(Expression.Negate(node.Operand, node.Method));
            default:
                return base.VisitUnary(node);
        }
    }
}

表达式
类型具有用于选中和未选中操作的每个运算符的单独版本。要将表达式主体中的任何
选中的
操作更改为
未选中的
操作,您不能将整个操作包装在
未选中的
表达式中。您需要遍历整个表达式树,找到选中操作的所有用法,并用这些操作的未选中版本替换它们

public static Expression MakeUnchecked(this Expression expression)
{
    return new UncheckedExpressionVisitor().Visit(expression);
}

public class UncheckedExpressionVisitor : ExpressionVisitor
{
    protected override Expression VisitBinary(BinaryExpression node)
    {
        switch (node.NodeType)
        {
            case ExpressionType.AddAssignChecked:
                return base.Visit(Expression.AddAssign(node.Left, node.Right));
            case ExpressionType.AddChecked:
                return base.Visit(Expression.Add(node.Left, node.Right));
            case ExpressionType.MultiplyAssignChecked:
                return base.Visit(Expression.MultiplyAssign(node.Left, node.Right));
            case ExpressionType.MultiplyChecked:
                return base.Visit(Expression.Multiply(node.Left, node.Right));
            case ExpressionType.SubtractAssignChecked:
                return base.Visit(Expression.SubtractAssign(node.Left, node.Right));
            case ExpressionType.SubtractChecked:
                return base.Visit(Expression.Subtract(node.Left, node.Right));
            default:
                return base.VisitBinary(node);
        }
    }

    protected override Expression VisitUnary(UnaryExpression node)
    {
        switch (node.NodeType)
        {
            case ExpressionType.ConvertChecked:
                return base.Visit(Expression.Convert(node.Operand, node.Type));
            case ExpressionType.NegateChecked:
                return base.Visit(Expression.Negate(node.Operand, node.Method));
            default:
                return base.VisitUnary(node);
        }
    }
}

我认为在LINQPad中的一个快速测试表明,如果您有
Add
Expression.NodeType
,它是未选中的,而
AddChecked
是带有检查的。这与此处的信息相匹配:这将两者区分开来,并以文件形式记录下来。(对于其他算术运算,也有类似的“选中”表达式)嗯,这可能和或者如果您在
checked
块中构造了表达式相一致?如果是这样,那么当你写
表达式expr=>()=>某物+10
,它将自动使用
AddChecked
表达式类型,但在关闭这些标志(或不在
checked
块中)的情况下,同一行将使用
Add
节点类型生成它。您可以提供更多关于如何生成表达式树的信息吗?我想LINQPad中的一个快速测试表明,如果您有
expression.NodeType
Add
它是未选中的,而
AddChecked
是带有选中的。这与此处的信息相匹配:这将两者区分开来,并以文件形式记录下来。(对于其他算术运算,也有类似的“选中”表达式)嗯,这可能和或者如果您在
checked
块中构造了表达式相一致?如果是这样,那么当你写
表达式expr=>()=>某物+10
,它将自动使用
AddChecked
表达式类型,但在关闭这些标志(或不在
checked
块中)的情况下,同一行将使用
Add
节点类型生成它。您能否提供更多关于如何生成表达式树的信息?