.NET Expression 从零开始五:循环(Loop)

       一直没有写关于”循环”方面的东西,今天我们来介绍“.NET Expression”中,动态的循环表达式应该如何编写,先说明一个明确的概念,在计算机中是不存在“计次循环[for]、判断循环[while]、判断循环尾[do...while]”的,只有“循环[loop]”C/C++/C#中都具有一个叫做“goto”的关键字,而“goto”关键字是对“jmp”指令的封装。

       以下是一个利用“.NET Expression”编写的一个很简单的“计次循环”函数,它将打印到 1--100 之间的数值到控制台回显上,同时返回最后的打印的值。

       以下代码展示了“continue”、“break”在表达式上的应用,事实上“return”与“break”的作用几乎是相同的,仅仅只是具有一小部分的不同,它们都是“流程跳出”指令,即你可以利用”break“替代”return“的作用,但对于”.NET Expression“而言,如果你想要使用”break“、”return“、”continue“几个指令,那么你必须定义”Loop“循环体的表达式,并且也仅仅只有”Loop“表达式的”Block“(代码块)区域可以被利用。

       一个好的”表达式编码“建议是默认定义一个类似如 ”do { /* block code */ } while(0, 0)“C类别语言表达式的”代码块结构“,利用它来控制”return“或”break“,否则你可以遭遇到一些”返回值“不适的问题,而动态表达式越强大那么对应的会越加复杂,在你并没有dotNET领域专家级的水平时,需稍稍注意这些问题,尽量减少欠下的”技术债务“,问题从来不是凭空而来,而是在代码的不断的迭代中逐步累积的,到了一个临界点就是”偿还技术债务“的时候。(来自本人的忠告)

namespace TECHMARS.VM
{
    using System;
    using System.Linq.Expressions;
    using System.Windows.Forms;

    class Program
    {
        [MTAThread]
        static void Main(string[] args)
        {
            ParameterExpression localvar_sequence = Expression.Parameter(typeof(int));
            LabelTarget break_label = Expression.Label(typeof(int));
            LabelTarget continue_label = Expression.Label(typeof(void));

            Func<int> expression = Expression.Lambda<Func<int>>(
                Expression.Block(new ParameterExpression[]
                {
                    localvar_sequence,
                }, new Expression[]
                {
                    Expression.Assign(localvar_sequence, Expression.Constant(0)),
                    Expression.Loop(
                        Expression.IfThenElse(
                            Expression.LessThan(localvar_sequence, Expression.Constant(100)),
                            Expression.Block(
                                Expression.AddAssign(localvar_sequence, Expression.Constant(1)),
                                Expression.Call(typeof(Console).GetMethod("WriteLine", new Type[]{ typeof(int)}), localvar_sequence),
                                Expression.Continue(continue_label, typeof(void))
                            ),
                            Expression.Break(break_label, localvar_sequence)), // push to eax/rax --> return value
                        break_label, continue_label),
                })
            ).Compile();
            MessageBox.Show(expression().ToString());
        }
    }
}

猜你喜欢

转载自blog.csdn.net/liulilittle/article/details/80801519