X# 包含 3 种相当相似但又不同的语言结构。
XBase 语言历来使用代码块类型。代码块指定为
{| params | expression }
代码块内的参数是 USUAL 类型,其返回值也是 USUAL 类型。
要对代码块进行评估,需要调用运行时函数 Eval(),并在需要时将代码块和参数传递给该函数。
FUNCTION Start() AS VOID
LOCAL cb as CODEBLOCK
cb := { |x, y| x * y}
? Eval(cb, 2,3) // 显示 6
WAIT
RETURN
您也可以使用表达式列表来代替单个表达式。列表中最后一个表达式的值将作为代码块的结果返回。
FUNCTION Start() AS VOID
LOCAL cb as CodeBlock
cb := { |x, y| x += 1, x * y}
? Eval(cb, 2,3) // 显示 9
WAIT
RETURN
Vulcan 语言还可以将语句列表作为代码块的 “主体”。最后一条语句的结果将返回给调用代码。当最后一条语句为 “Void ”时,将返回 NIL:
请注意,结尾的卷边必须独立成行,第一条语句也必须在新的一行中出现。
FUNCTION Start() AS VOID
LOCAL cb as CodeBlock
cb := { |x, y|
x += 1
? x
RETURN x * y
}
? Eval(cb, 2,3) // prints 3 and shows the result 9
WAIT
RETURN
Lamda 表达式看起来很像 Codeblocks。它们通常与委托结合使用。
DELEGATE MultiPlyInt( x as Int, y as Int) as Int
FUNCTION Start() AS VOID
LOCAL lambda as MultiPlyInt
lambda := { x, y => x * y}
? Lambda(2,3) // shows 6
RETURN
参数是可选的,返回类型可以是 VOID,因此也可以这样做
DELEGATE DoSomething( ) as VOID
FUNCTION Start() AS VOID
LOCAL lambda as DoSomething
lambda := { => Console.WriteLine("This is a Lambda")}
Lambda() // prints the text
RETURN
Lambda 表达式的参数可以类型化。这不仅便于文档记录,还能帮助编译器找到方法的正确重载:
DELEGATE CalcInt( x AS INT, y AS INT) AS INT
DELEGATE CalcReal( x AS REAL8, y AS REAL8) AS REAL8
FUNCTION Start() AS VOID
TestLambda( { x AS INT, y AS INT => x * y} )
TestLambda( { x AS REAL8, y AS REAL8 => x + y} )
TestLambda( { x , y => x - y } ) // Which one will be called ?
RETURN
FUNCTION TestLambda (lambda AS CalcInt) AS VOID
? "Int", lambda(2,3)
RETURN
FUNCTION TestLambda (lambda AS CalcReal) AS VOID
? "Real",lambda(2,3)
RETURN
Lambda 的主体也可以是单个表达式、表达式列表和语句列表。
匿名方法表达式
其工作原理与 Lambda 表达式几乎相同。
请看下面的例子:
FUNCTION TestAnonymous() AS VOID
LOCAL oForm AS Form
oForm := Form{}
oForm:Click += DELEGATE(o AS System.Object, e AS System.EventArgs ) {
System.Windows.Forms.MessageBox.Show("Click from AME 1!")
System.Windows.Forms.MessageBox.Show("Click from AME 2!")
}
oForm:Click += { o,e => System.Windows.Forms.MessageBox.Show("We can also do this with a Lambda!") }
oForm:ShowDialog()
RETURN
Lambda 表达式与匿名方法表达式的最大区别在于,Lambda 表达式的参数无需类型化。它们将从用法中推断出来。匿名方法表达式的参数必须始终键入。