一直没有写关于”循环”方面的东西,今天我们来介绍“.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());
}
}
}