C#10新特性-lambda 表示式和方法組的改進

Eric zhou發表於2022-03-09

C# 10 中對Lambda的語法和型別進行了多項改進:

1. Lambda自然型別

Lambda 表示式現在有時具有“自然”型別。 這意味著編譯器通常可以推斷出 lambda 表示式的型別。

到目前為止,必須將 lambda 表示式轉換為委託或表示式型別。

在大多數情況下,我們會在 BCL 中使用過載的 Func<...> 或 Action<...> 委託型別之一:

從 C# 10 開始,如果 lambda 沒有這樣的“目標型別”,.NET 將嘗試計算一個:

滑鼠懸停在 var parse 上,然後檢視型別仍然是 Func<int, string>

編譯器將使用可用的 Func 或 Action 委託(如果存在合適的委託)。 否則,它將合成一個委託型別.

並非所有 lambda 表示式都有自然型別——有些只是沒有足夠的型別資訊。 例如,放棄引數型別將使編譯器無法決定使用哪種委託型別:

lambda 的自然型別意味著它們可以分配給較弱的型別,例如 object 或 Delegate:

當涉及到表示式樹時,我們結合了“目標”和“自然”型別。 如果目標型別是 LambdaExpression 或非泛型 Expression(所有表示式樹的基型別)並且 lambda 具有自然委託型別 D,將改為生成 Expression<D>:

2. 方法組的自然型別

方法組(即沒有引數列表的方法名稱)現在有時也具有自然型別。.NET 能夠將方法組轉換為相容的委託型別:

現在,如果方法組只有一個過載,它將具有自然型別:

3. Lambda返回型別

在前面的示例中,Lambda表示式的返回型別是顯而易見的,並被推斷出來的。 但是也有特殊情況:

在 C# 10 中,可以在 lambda 表示式上指定顯式返回型別,就像在方法或本地函式上一樣。

返回型別在引數之前。

當指定一個顯式的返回型別時,引數必須用括號括起來,這樣編譯器或其他開發人員不會太混淆:

4. Lambda的屬性
從 C# 10 開始,可以將屬性放在Lambda 表示式上,就像對方法和本地函式一樣。 當有屬性時,Lambda  的引數列表必須用括號括起來:

就像本地函式一樣,如果屬性在 AttributeTargets.Method 上有效,則可以將屬性應用於 lambda。

Lambda 的呼叫方式與方法和本地函式不同,因此在呼叫 lambda 時屬性沒有任何影響。 但是,lambdas 上的屬性對於程式碼分析仍然有用,並且可以通過反射發現它們。

 

C#10新特性-lambda 表示式和方法組的改進

 

周國慶

2022/3/8

相關文章