Несколько операторов в выражении переключателя с # 8
Выражение переключения было введено в C# 8. В кодовой базе есть много мест, которые можно переписать в новом стиле.
Итак, у меня есть код, который используется для разбора пакетов из потока байтов:
switch (command)
{
case Command.C1:
return new P1();
case Command.C2:
return new P2();
default:
stream.Position++;
return null;
}
Проблема в том, что его нельзя преобразовать в выражение переключения, подобное этому
return command switch
{
Command.C1 => new P1(),
Command.C3 => new P2(),
_ => { stream.Position++; return null; }
};
Первое, что пришло мне в голову, это использовать Func, и он компилирует:
return command switch
{
Command.C1 => new P1(),
Command.C3 => new P2(),
_ => new Func<AbstractPacket>(() => { stream.Position++; return null; })()
};
F# уже позволяет писать код с несколькими операторами в каждой ветке:
match command with
| Command.C1 -> Some(P1() :> AbstractPacket)
| Command.C2 -> Some(P2() :> AbstractPacket)
| _ ->
stream.Position <- stream.Position + 1
None
Теперь я предпочитаю использовать оператор-переключатель, но есть ли возможность записать это как выражение-переключатель без каких-либо странных хаков?
1 ответ
Ваш единственный поддерживаемый выбор - это функция, как и вы. см. эту статью для получения дополнительной информации. Его пример:
var result = operation switch
{
"+" => ((Func<int>)(() => {
Log("addition");
return a + b;
}))(),
"-" => ((Func<int>)(() => {
Log("subtraction");
return a - b;
}))(),
"/" => ((Func<int>)(() => {
Log("division");
return a / b;
}))(),
_ => throw new NotSupportedException()
};
Просто потому, что он новый, не означает, что он лучший для всех сценариев использования. Он не предназначен для использования нескольких команд.
С участием:
TRes Call<TRes>(Func<TRes> f) => f();
это выглядит так:
return command switch {
Command.C1 => new P1(),
Command.C3 => new P2(),
_ => Call(() => { stream.Position++; return null; }),
};
или же:
var result = operation switch {
"+" => Call(() => {
Log("addition");
return a + b;
}),
"-" => Call(() => {
Log("subtraction");
return a - b;
}),
"/" => Call(() => {
Log("division");
return a / b;
}),
_ => throw new NotSupportedException(),
};