共用方式為


Target-Typed 條件表達式

注意

本文是功能規格。 規格可作為功能的設計檔。 其中包含建議的規格變更,以及功能設計和開發期間所需的資訊。 這些文章會發佈,直到提議的規格變更完成並併併入目前的ECMA規格為止。

功能規格與已完成實作之間可能有一些差異。 這些差異是在的相關 語言設計會議(LDM)記錄中擷取的。

您可以在 規範一文中瞭解更多關於如何將功能小規格納入 C# 語言標準的過程

條件表達式轉換

若為條件表達式 c ? e1 : e2,則為

  1. e1e2沒有常見的類型, 或
  2. 其中一般類型存在,但其中一個表達式 e1e2 沒有隱含轉換成該類型

我們會定義新的隱含 條件表達式轉換,允許從條件表達式隱含轉換成任何類型 T,其中從 e1 轉換成 T,以及從 e2 轉換成 T。 如果條件表達式在 e1e2 之間沒有通用型別,也不受限於 條件表示式轉換,則為錯誤。

從表達式進行更好的轉換

我們變更

從表達式進行更好的轉換

假設有一個隱式轉換 C1 將表達式 E 轉換成類型 T1,以及一個隱式轉換 C2 將表達式 E 轉換成類型 T2。如果 E 不完全符合 T2,並且至少滿足以下條件之一,則 C1 是比 C2 更好的轉換

從表達式進行更好的轉換

假設有一個隱含轉換 C1,將表達式 E 轉換為類型 T1,還有一個隱含轉換 C2,將表達式 E 轉換為類型 T2,如果 ET2 不完全相符,並且下列條件至少有一個成立,則 C1 是比 C2 更好的 轉換

  • E 完全符合 T1.12.6.4.5
  • 不是 條件表達式轉換, 是條件表達式轉換
  • T1 是比 T2 更好的轉換目標(•12.6.4.7,且 C1C2 要麼都是 條件表達式轉換,或兩者都不是 條件表達式轉換

轉換表達式

目前的 C# 語言規格說

形式為 (T)Ecast_expression,其中 T類型,而 Eunary_expression,則會將 E 的值明確轉換為 T類型(§10.3)。

條件表示式轉換 的情況下,可能會有超過一種從 E 轉換到 T的方式。 加上 條件表示式轉換,我們偏好將任何其他轉換轉換成 條件表達式轉換,並且只使用 條件表達式轉換 做為最後手段。

設計注意事項

原因是為了更好地從表達式 轉換為 ,以處理如下情況:

M(b ? 1 : 2);

void M(short);
void M(long);

這種方法確實有兩個小缺點。 首先,它與 switch 運算式不同:

M(b ? 1 : 2); // calls M(long)
M(b switch { true => 1, false => 2 }); // calls M(short)

這仍然是一項重大變更,但其範圍不太可能影響實際程式:

M(b ? 1 : 2, 1); // calls M(long, long) without this feature; ambiguous with this feature.

M(short, short);
M(long, long);

這變得模棱兩可,因為對第一個參數的轉換到 long 更佳(因為它不使用 條件表達式轉換),然而,對第二個參數來說,轉換到 short 更佳(因為 short 是比 long更佳的 轉換 目標)。 這項重大變更似乎較不嚴重,因為它不會以無訊息方式變更現有程序的行為。

轉換表示式附註的原因是為了處理如下所示的情況:

_ = (short)(b ? 1 : 2);

此程式目前會使用從 intshort的明確轉換,而我們想要保留此程式目前的語言意義。 變更在運行時間是無法觀察的,但透過下列程式,可以觀察變更:

_ = (A)(b ? c : d);

其中 c 的類型為 Cd 類型為 D,而且有從 C 轉換成 D的隱含使用者定義轉換,以及從 DA的隱含使用者定義轉換,以及從 CA的隱含使用者定義轉換。 如果在 C# 9.0 之前編譯此程式代碼,當 b 為 true 時,我們會從 c 轉換成 D,然後轉換成 A。 如果我們使用 條件表達式轉換,則當 b 為 true 時,我們會直接從 c 轉換成 A,這會執行不同的使用者程式代碼序列。 因此,我們將 條件表達式轉換 視為轉型的最後手段,以保留現有的行為。