2014-09-23 68 views
1

在我的表達式樹(使用Expression類創建)中,我需要將我的代碼包裝在一個未經檢查的塊中(http://msdn.microsoft.com/en-us/library/a569z7k8.aspx),但是怎麼做? Expression類型沒有什麼有趣的。如何爲未經檢查的語句創建表達式樹語句

+0

LINQPad中的一個快速測試我認爲如果你有'Add'的Expression.NodeType'沒有選中,並且'AddChecked'正在檢查。這與這裏的信息匹配:http://msdn.microsoft.com/en-us/library/bb361179%28v=vs.110%29.aspx區分這兩者,並記錄在案。 (其他算術運算有類似的「檢查」) – 2014-09-23 20:45:46

+0

嗯,也許這與['/ checked'編譯器標誌](http://msdn.microsoft.com/en-us/library/h25wtyxf。 aspx)或者如果你已經在'checked'塊中構建了你的表達式?如果是這樣,那麼當你寫'Expression expr =>()=> something + 10;'時,它將自動使用AddChecked表達式類型,但是這些標誌關閉(或不在'checked'塊中)行將使用「Add」節點類型生成它。你能否提供給我們更多關於你如何製作表情樹的信息? – 2014-09-23 20:49:58

回答

4

Expression類型對於已檢查和未檢查的操作具有不同版本的每個運算符。要將表達式正文中的任何checked操作更改爲unchecked操作,您不能將整個事件包裝在unchecked表達式中。您需要遍歷整個表達式樹,查找檢查操作的所有用法,並將它們替換爲這些操作的未檢查版本。

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); 
     } 
    } 
}