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

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