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

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

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

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

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

DynamicExpression:表示動態操作。這個網上可見的資料少得可憐,但想到MVC和第三方的動態語言能在NET運行。好奇的倒騰了下先聲明兩個類(有相同的方法和字段,但不是繼承于同一接口的類),設想是動態調用它們的方法和字段。

    class AiTestD        {            public string Name = "你好!這是 AiTestD";            public int Id = 123;            public static string AiTest(string ai1, string ai2)            {                return ai1 + ai2;            }            public static int add(int a, int b)            {                return a + b;            }            public int add2(int a, int b)            {                return -(a + b);            }        }        class AiTestD2        {            public string Name = "你好!這是 AiTestD2";            public int Id = 789;            public static string AiTest(string ai1, string ai2)            {                return "**" + ai1 + ai2;            }            public static int add(int a, int b)            {                return (a + b) * 1000;            }            public int add2(int a, int b)            {                return -(a + b) * 1000;            }        }

第一個方法 AiDynamicDo,要實現的是獲取兩個類的Id屬性質(這里是值類型操作,剛開始時,定義的是typeof(Func<CallSite, object, int>,總是編譯不過,發現在 Expression.MakeDynamic 中的參數,只要是值類型都是通不過的,只有通過Expression.Convert轉換成 typeof(object),才可以,但引用類型是不用轉換的)

        /// <summary>        /// 獲取字段        /// </summary>        /// <param name="aiD"></param>        static void AiDynamicDo(dynamic aiD)        {            //聲明參數            ParameterExpression paramExpr = Expression.Parameter(typeof(object), "o");            //獲取 CallSite 以支持調用時的運行時。            //CallSiteBinder 是必需的        //注意這里用的是     Binder.GetMember            CallSiteBinder aiBinder = Binder.GetMember(CSharpBinderFlags.None, "Id", typeof(Program),                new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });            //定義一個動態表達式            //Func<CallSite, object, object>聲明方式中 CallSite 是動態調用站點的基類。 此類型用作動態站點目標的參數類型。            //就是上面的 aiBinder,第二個參數是要傳入的動態類型 用dynamic關鍵字也是可以的,            //后面的參數是實際調用和返回的參數            //不過操作中發現在返回值一定要用 object 不然會編譯不過            //當然也可用Action<CallSite, object,...>,除了沒返回值,參數要求和用Func<CallSite, object, object>是一樣的。                       DynamicExpression Dynamic2 =              Expression.MakeDynamic(typeof(Func<CallSite, object, object>),                 aiBinder, paramExpr          );            //編譯            LambdaExpression laExp = Expression.Lambda(                Expression.Block(                new ParameterExpression[] { paramExpr },                Expression.Assign(paramExpr, Expression.Constant(aiD))              , Dynamic2));            //執行            Console.WriteLine("AiDynamicDo:" + laExp.ToString());            Console.WriteLine("結果:" + laExp.Compile().DynamicInvoke());            Console.WriteLine();        }

調用:

      AiDynamicDo(new AiTestD());      AiDynamicDo(new AiTestD2());

輸出為:      AiDynamicDo:() => {var o; ... }     結果:123     AiDynamicDo:() => {var o; ... }     結果:789

    /// <summary>        /// 字段2        /// </summary>        /// <param name="aiD"></param>        static void AiDynamicDo2(dynamic aiD)        {            //Binder.Convert            CallSiteBinder aiBinder = Binder.Convert(CSharpBinderFlags.None, typeof(object), typeof(Program));            ParameterExpression paramExpr = Expression.Parameter(aiD.GetType(), "o");            MemberExpression namePropExpr = Expression.Field(paramExpr, "Name");            var Dynamic2 = Expression.MakeDynamic(typeof(Func<CallSite, object, object>)                , aiBinder                , namePropExpr          );            LambdaExpression laExp = Expression.Lambda(              Expression.Block(              new ParameterExpression[] { paramExpr },              Expression.Block(Expression.Assign(paramExpr, Expression.Constant(aiD))              )             , Dynamic2));            Console.WriteLine("AiDynamicDo2:" + laExp.ToString());            Console.WriteLine("結果:" + laExp.Compile().DynamicInvoke());            Console.WriteLine();        }        /// <summary>        /// 引用類型方法調用測試 Binder.Convert        /// </summary>        /// <param name="aiD"></param>        static void AiDynamicDo3(dynamic aiD)        {            //Binder.Convert            CallSiteBinder aiBinder = Binder.Convert(CSharpBinderFlags.None, typeof(object), typeof(Program));            ParameterExpression aiparamExpr = Expression.Parameter(aiD.GetType(), "o");            ParameterExpression aiParamExpr1 = Expression.Parameter(typeof(string), "a");            ParameterExpression aiParamExpr2 = Expression.Parameter(typeof(string), "b");            MethodCallExpression aiMth = Expression.Call(                null, aiD.GetType().GetMethod("AiTest", new Type[] { typeof(string), typeof(string) }), aiParamExpr1, aiParamExpr2);            var Dynamic2 =              Expression.MakeDynamic(              typeof(Func<CallSite, dynamic, object>),              aiBinder, aiMth          );            LambdaExpression laExp = Expression.Lambda(Dynamic2, aiParamExpr1, aiParamExpr2);            Console.WriteLine("AiDynamicDo3:" + laExp.ToString());            Console.WriteLine("結果:" + laExp.Compile().DynamicInvoke("AiTest-", "動態調用"));            Console.WriteLine();        }        /// <summary>        /// 值類型方法調用測試 Binder.Convert        /// </summary>        /// <param name="aiD"></param>        static void AiDynamicDo4(dynamic aiD)        {            CallSiteBinder aiBinder = Binder.Convert(CSharpBinderFlags.None, typeof(object), typeof(Program));            ParameterExpression aiParamExpr = Expression.Parameter(aiD.GetType(), "o");            ParameterExpression aiParamExpr1 = Expression.Parameter(typeof(int), "a");            ParameterExpression aiParamExpr2 = Expression.Parameter(typeof(int), "b");            MethodCallExpression aiMth = Expression.Call(                null, aiD.GetType().GetMethod("add", new Type[] { typeof(int), typeof(int) }), aiParamExpr1, aiParamExpr2);            var Dynamic2 =              Expression.MakeDynamic(              typeof(Func<CallSite, dynamic, object>),             aiBinder,              Expression.Convert(aiMth, typeof(object)) //!!這里要轉換,否剛不能通過          );            //LambdaExpression laExp = Expression.Lambda(Dynamic2, paramExpr1, paramExpr2);            LambdaExpression laExp = Expression.Lambda(                 Expression.Block(                new ParameterExpression[] { aiParamExpr1, aiParamExpr2 },                Expression.Block(Expression.Assign(aiParamExpr1, Expression.Constant(30)),                Expression.Assign(aiParamExpr2, Expression.Constant(40))                ),                Dynamic2                )            );            Console.WriteLine("AiDynamicDo4:" + laExp.ToString());            Console.WriteLine("結果:" + laExp.Compile().DynamicInvoke());            Console.WriteLine();        }    //與上例不同的是,本過程不是調用的反射方法        static void AiDynamicDo5(dynamic aiD)        {            //當調用方法是void類型時 應該用 CSharpBinderFlags.ResultDiscarded            //第二個參數是方法名            //第三個參數要泛型時才結出            //第五個參數要與表達示參數據相同            var aiBinder = Binder.InvokeMember(CSharpBinderFlags.None, "add2", null, typeof(Program),               new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),                   CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });            ParameterExpression aiParamExpr = Expression.Parameter(typeof(object), "o");            ParameterExpression aiParamExpr1 = Expression.Parameter(typeof(int), "a");            ParameterExpression aiParamExpr2 = Expression.Parameter(typeof(int), "b");        //與上例中不同的地方            DynamicExpression aiDynamic = Expression.MakeDynamic(typeof(Func<CallSite, object, int, int, object>)              , aiBinder              , aiParamExpr              , aiParamExpr1              , aiParamExpr2          );            //下面這種使用方式,在調用時Dyna
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 汉寿县| 龙胜| 青岛市| 宝兴县| 大竹县| 宁陵县| 敦化市| 隆安县| 凉城县| 轮台县| 丰镇市| 互助| 长宁区| 巫溪县| 桂东县| 安陆市| 奎屯市| 孟津县| 临海市| 南皮县| 哈密市| 和平县| 榆树市| 安顺市| 和硕县| 涞水县| 绥芬河市| 张北县| 隆尧县| 繁昌县| 延吉市| 怀仁县| 盐亭县| 绥德县| 独山县| 辽中县| 佛冈县| 得荣县| 腾冲县| 同仁县| 台北县|