美文网首页
C# 表达式树 (17)

C# 表达式树 (17)

作者: wwmin_ | 来源:发表于2021-02-09 16:16 被阅读0次

    系列文章: C# 表达式树及其应用 (Expression 类)

    本节继续讲解Expression相关的API, 力争把相关api 都使用简短demo说明一下

    • TryFault 创建一个表示 try 块的 TryExpression,该 try 块包含一个 fault 块,但不包含 catch 语句。
    //TryFault   创建一个表示 try 块的 TryExpression,该 try 块包含一个 fault 块,但不包含 catch 语句。
        void TryFaultSample()
        {
            TryExpression tryCatchExpr = Expression.TryFault(
                Expression.Block(
                    Expression.Throw(Expression.Constant(new DivideByZeroException())),
                    Expression.Constant("Try block")
                ),
                Expression.Call(typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })!, Expression.Constant("Fault block"))//Finally block | 
            );
            //Expression.Lambda<Func<string>>(tryCatchExpr).Compile()().Dump("TryFault");//TryFault报错未捕捉
        }
        TryFaultSample();
    
    • TryFinally 创建一个表示 try 块的 TryExpression,该 try 块包含一个 finally 块,但不包含 catch 语句。 同TryFault
        //TryFinally   创建一个表示 try 块的 TryExpression,该 try 块包含一个 finally 块,但不包含 catch 语句。 同TryFault
    
        //TryGetActionType  创建一个 Type 对象,它表示具有特定类型参数的泛型 System.Action 委托类型。//TODO
    
        //TryGetFuncType   创建一个 Type 对象,它表示具有特定类型参数的泛型 System.Func 委托类型。 最后一个类型参数指定已创建委托的返回类型。//TODO
    
    • TypeAs 创建一个表示显式引用或装箱转换的 UnaryExpression(如果转换失败,则提供 null)。
        //TypeAs   创建一个表示显式引用或装箱转换的 UnaryExpression(如果转换失败,则提供 null)。
        void TypeAsSample()
        {
            UnaryExpression typeAsExpression = Expression.TypeAs(Expression.Constant(3, typeof(int)), typeof(int?));
            typeAsExpression.ToString().Dump("TypeAs");//(3 As Nullable`1)
        }
        TypeAsSample();
    
    • TypeEqual 创建一个比较运行时类型标识的
        //TypeEqual   创建一个比较运行时类型标识的 TypeBinaryExpression。//TODO
        
        //TypeIs   创建一个 TypeBinaryExpression。
        void TypeIsSample(){
            TypeBinaryExpression typeBindaryExpression = Expression.TypeIs(Expression.Constant("www"),typeof(int));
            typeBindaryExpression.ToString().Dump("TypeIs");
        }
        TypeIsSample();
        
        //UnaryPlus    创建一个表示一元正运算的 UnaryExpression。
        void UnaryPlusSample(){
            UnaryExpression ue = Expression.UnaryPlus(Expression.Constant(1,typeof(int)));
            ue.ToString().Dump("UnaryPlus");//+1
        }
        UnaryPlusSample();
    
        //Unbox    创建一个表示显式取消装箱的 UnaryExpression。//TODO
    
    • Variable 创建一个 ParameterExpression 节点,该节点可用于标识表达式树中的参数或变量。
        //Variable   创建一个 ParameterExpression 节点,该节点可用于标识表达式树中的参数或变量。
        void VariableSampel()
        {
            ParameterExpression variableExpr = Expression.Variable(typeof(int), "sampleVar");//the parameter expression is used to create a variable;
            BlockExpression addAssignExpr = Expression.Block(
            new ParameterExpression[] { variableExpr },
            Expression.Assign(variableExpr, Expression.Constant(1)),
            Expression.AddAssign(
                variableExpr,
                Expression.Constant(2)
                )
            );
            addAssignExpr.Expressions.ForEach(p => p.ToString().Dump());//(sampleVar = 1),(sampleVar +=2)
            Console.WriteLine(Expression.Lambda<Func<int>>(addAssignExpr).Compile()());//3
        }
        VariableSampel();
        
        //VisitChildren   简化节点,然后对简化的表达式调用访问者委托。 该方法在节点不可简化时引发异常。//TODO
    

    补充: 前面可能用到的方法和类

    /*
    * 定义扩展
    */
    public static class Utils
    {
    
        /// <summary>
        /// 扩展IEnumerable ForEach
        ///<para>遍历IEnumerable 执行action</para>
        /// </summary>
        public static void ForEach<TSource>(this IEnumerable<TSource> source, Action<TSource> action)
        {
            using IEnumerator<TSource> enumerator = source.GetEnumerator();
            while (enumerator.MoveNext())
            {
                TSource current = enumerator.Current;
                action(current);
            }
        }
    }
    
    //4. 方法
    //Accept(ExpressionVisitor) //调度到此节点类型的特定 Visit 方法。 例如,MethodCallExpression 调用 VisitMethodCall(MethodCallExpression)。
    
    //示例用到的公共test class
    public class Person
    {
        public string Name { get; set; } = null!;
        public string GetName() => this.Name;
        public string GetOrSetName(string name)
        {
            if (this.Name == null) this.Name = name;
            return this.Name;
        }
    }
    
    
    
    //Add(Expression, Expression, MethodInfo) 创建一个表示不进行溢出检查的算术加法运算的 BinaryExpression。 可指定实现方法。
    public class Plus
    {
        //下面表达式指定加法的实现
        public static int AddOne(int a, int b)
        {
            return a + b + 1;
        }
    }
    
    
    //Bind   创建一个表示成员初始化的 MemberAssignment。
    public class TestBindMember
    {
        public int Num { get; set; }
    }
    
    
    //Call    创建一个 MethodCallExpression。
    public class SmapleClass
    {
        public int AddIntegers(int arg1, int arg2)
        {
            return arg1 + arg2;
        }
    }
    
    //Field     创建一个表示访问字段的 MemberExpression。
    public class TestFieldClass
    {
        public int num = 10;
    }
    
    //ListBind
    class TestListBindClass
    {
        public TestListBindClass()
        {
            Nums = new List<int>();
        }
        public List<int> Nums { get; set; }
    }
    

    到此这个系列就结束, 有时间的话在将里面的TODO不定时的补充上去, 望各位多提意见多补充, 谢谢...

    本文作者:wwmin
    微信公众号: DotNet技术说
    本文链接:https://www.jianshu.com/p/d789663ffb79
    关于博主:评论和私信会在第一时间回复。或者[直接私信]我。
    版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
    声援博主:如果您觉得文章对您有帮助,关注点赞, 您的鼓励是博主的最大动力!

    相关文章

      网友评论

          本文标题:C# 表达式树 (17)

          本文链接:https://www.haomeiwen.com/subject/twkcxltx.html