国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

表達式:使用API創建表達式樹(1)

2019-11-17 03:18:48
字體:
來源:轉載
供稿:網友

表達式:使用API創建表達式樹(1)

表達式樹可使用ExPRessions類的靜態工廠方法來創建。這種用API的方式創建給予我們在編程極大的靈活性,MSDN上關于表達式的例子也不少,但在使用過程中還是會遇到許多麻煩,對有的表達式類,介紹得不是太清楚。這里把一些常見的表達示類的使用整理了下。BinaryExpression類: 是表示包含二元運算符的表達式。   比如構建形如 (100+88)是個典型的 a+b 式的二元計算,表達式代碼如下

BinaryExpression binaryexp = Expression.MakeBinary                 (ExpressionType.Add, Expression.Constant(100), Expression.Constant(88));Console.WriteLine(Expression.Lambda(binaryexp).Compile().DynamicInvoke());

輸出: 188

MakeBinary是在Expressions中定義的一個靜態工廠方法(根據ExpressionType來選擇調用),最終調用的是Expression.Add 靜態方法所以是與下面操作等效的

BinaryExpression binaryexp = Expression.Add(Expression.Constant(100), Expression.Constant(88));

a+b的值類型的操作比較簡單,但如果是 "100"+"88" 呢,改下上面的操作

BinaryExpression binaryexp = Expression.Add(Expression.Constant("100"), Expression.Constant("88"));Console.WriteLine(Expression.Lambda(binaryexp).Compile().DynamicInvoke());

但這時會報錯 “沒有為類型“System.String”和“System.String”定義二進制運算符 Add”,這是怎么回事,在我們代碼時如果寫 string s= "100"+"88";是沒錯的啊。實際上字串的 + 在生成IL代碼時,會轉換成 string 的 Concat 擴展方法來操作。因此要實現如 "100"+"88" 還是稍顯麻煩第一步:獲取Concat方法的MethodInfo MethodInfo mif = typeof(string).GetMethods().First(m => m.Name == "Concat" && m.GetParameters().Length ==2); 因為Concat的參數是可變的方法參數,獲取MethodInfo,一定要加上m.GetParameters().Length=實際調用時的參數個數據,不然會出現參數不匹配錯誤。第二步:使用MakeBinary的另一個重載方法

    BinaryExpression binaryexp = Expression.Add(Expression.Constant("100"), Expression.Constant("88"), mif);    Console.WriteLine(Expression.Lambda(binaryexp).Compile().DynamicInvoke());

輸出: 10088

回頭再看 Expression.Add 的實現

 if (!(method == (MethodInfo) null))        return Expression.GetMethodBasedBinaryOperator(ExpressionType.Add, left, right, method, true);      if (left.Type == right.Type && TypeUtils.IsArithmetic(left.Type))        return (BinaryExpression) new SimpleBinaryExpression(ExpressionType.Add, left, right, left.Type);      else        return Expression.GetUserDefinedBinaryOperatorOrThrow(ExpressionType.Add, "op_Addition", left, right, true);

從中看出,當參數年method為null 時,實際上要檢查 TypeUtils.IsArithmetic(left.Type),而IsArithmetic的定義為

  internal static bool IsArithmetic(Type type)    {      type = TypeUtils.GetNonNullableType(type);      if (!type.IsEnum)      {        switch (Type.GetTypeCode(type))        {          case TypeCode.Int16:          case TypeCode.UInt16:          case TypeCode.Int32:          case TypeCode.UInt32:          case TypeCode.Int64:          case TypeCode.UInt64:          case TypeCode.Single:          case TypeCode.Double:            return true;        }      }      return false;    }

所以Expression.Add(Expression.Constant("100"), Expression.Constant("88"))在不給定操作方法時,會報錯。當指定操作方法時,表達式雖然用tostring 是 "100"+"88" ,但調用的操作方法是 string.Concat。就象用方法表達式一樣MethodCallExpression methExp = Expression.Call(mif, Expression.Constant("100"), Expression.Constant("88"));因此在調用 Expression.Lambda(binaryexp).Compile().DynamicInvoke();和 Expression.Lambda(methExp).Compile().DynamicInvoke();的結果是一樣的另外從 if (left.Type == right.Type && TypeUtils.IsArithmetic(left.Type)) 前部分看,Add方法是要求類型完全相同,在看上去可行的表達式 Expression.Add(Expression.Constant(100), Expression.Constant(88.0)) (后面是Double類型 ),也會報錯。而就當改為Expression.Add(Expression.Constant((Double)100), Expression.Constant(88.0)) 或 Expression.Add(Expression.Constant(100.0), Expression.Constant(88.0)) 。


上一篇:【轉載】#274

下一篇:【轉載】#273

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阿克| 孟津县| 柯坪县| 丽江市| 青州市| 建阳市| 永春县| 十堰市| 衡山县| 汕尾市| 普洱| 平凉市| 连江县| 东兴市| 西宁市| 丰宁| 扎兰屯市| 军事| 噶尔县| 万荣县| 武胜县| 体育| 河北区| 文昌市| 二连浩特市| 大名县| 突泉县| 井冈山市| 卢湾区| 南召县| 鱼台县| 揭阳市| 晋江市| 墨竹工卡县| 红桥区| 辽阳市| 阜阳市| 衡山县| 通山县| 涡阳县| 海阳市|