[英]C# 8 switch expression for void methods
我知道用於返回值或屬性匹配的方法的C# 8
switch expression
語法。 但是如果我們只需要打開一個字符串值並執行一個不返回任何內容(無返回類型/void)的方法,那么我們如何處理它呢? 我正在考慮某種形式的 Func 但不確定確切的語法。 我知道我們可以用常規的 case 語句用舊的方式來做,但試圖看看我們是否可以用新的語法來實現同樣的效果。
這是問題的示例
switch (stringvalue)
{
case "Add": Add(); break;
case "Subtract": Subtract(); break;
}
可能像:
stringvalue switch
{
"Add" => Add(),
"Subtract" => Subtract()
}
// but this complains that there needs to be assignment on left side for this
這可能嗎?
這不可能。 在C# 8
switch expression
不能返回void
。 它必須返回一個值,並且必須使用該值(分配給變量,作為參數傳遞給方法,作為方法的結果返回等)。 但是有一個解決方法。 我們可以編寫一個switch expression
,它返回一個delegate
(例如Action
類型),然后立即調用它:
(stringValue switch
{
"Add" => (Action) Add,
"Subtract" => Subtract,
_ => throw new ArgumentOutOfRangeException()
})();
這種方法也可以與expression bodied methods
一起使用。 這是演示。
這可能嗎?
在C# 8
中這是不可能的。 C# specification
中描述了此限制。
讓我們參考C# specification
。 從頁面Recursive Pattern Matching - Switch Expression
和Statements
我們可以了解到:
switch_expression
不允許作為expression_statement
。
一個
expression_statement
計算一個給定的表達式。 表達式計算的值(如果有)將被丟棄。
從這兩個語句我們可以得出結論, switch_expression
不能在expression_statement
的上下文中使用,它的結果值也不能被丟棄。 必須使用結果值,例如,它必須分配給變量、作為參數傳遞給方法或作為方法的結果返回。 因此編譯器抱怨switch expression
不能用作語句。
如果我們只需要打開一個字符串值並執行一個不返回任何內容(無返回類型/void)的方法,那么我們如何 go? 我正在考慮某種形式的 Func 但不確定確切的語法。
我們可以使用下一種方法:編寫一個switch expression
,它返回一個delegate
,然后立即調用它。 例如:
(stringValue switch
{
"Add" => (Action) Add,
"Subtract" => Subtract,
_ => throw new ArgumentOutOfRangeException()
})();
此方法也可用於聲明expression bodied members
:
private static void Demo(string str) =>
(str switch
{
"Add" => (Action) Add,
"Subtract" => Subtract,
_ => throw new ArgumentOutOfRangeException()
})();
這是完整的示例。
在我看來,這種解決方法看起來很丑陋,我個人更喜歡使用switch-case
或if-else
而不是這種結構。
可能在C#
的未來版本中此限制將放寬( 請參閱此鏈接):
switch_expression
不允許作為expression_statement
。我們正在考慮在未來的修訂中放寬這一點。
但是我在csharplang repo
中沒有找到合適的建議。
正如伊利亞爾告訴你的那樣,這是不可能的。 我有時使用的一種解決方法是添加一個始終返回 true 的本地 function,並且我在開關分配中使用了一個丟棄字符。 我發現這個解決方法比使用代表的方法更清晰一些。
例如,您可以在切換之前將此添加到您的代碼中:
bool Add() { [HEREYOURCODEToAdd]; return true;}
bool Substract() { [HEREYOURCODETOSubstract]; return true;}
然后你會這樣稱呼它:
_ = stringvalue switch {
"Add" => Add(),
"Substract" => Substract(),
};
我認為這種方法有一些用例。 例如,如果你想在 switch 中使用元組模式,它會比許多 annidated ifs 更具可讀性。 這是我正在使用的代碼,我認為這種方法比 ifs 更好:
bool agregar(int índiceInicial, int índiceFinal) { visitasJson.Add(json[índiceInicial..índiceFinal]); return true; };
_ = (índiceInicial, índiceFinal) switch {
(0, -1) => agregar(índiceInicial + 1, índiceFinal - 3),
(_, -1) => agregar(índiceInicial, índiceFinal - 1),
(0, _) => agregar(índiceInicial + 5, índiceFinal),
(_, _) => agregar(índiceInicial, índiceFinal),
};
你真的想在你的用例中使用 switch 表達式嗎,傳統的方式要好得多。
所有建議的解決方案(如代表、丟棄)都是解決方法。
您試圖錯誤地使用 switch 表達式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.