C# 有没有 Rust 和 Lisp 那样, if/match 能直接求值,像三目运算符一样的功能?

311 天前
 LaTero

最近 Unity DOTS 进入 LTS 了,想试一试,平时 C#用得少,全凭 IDE 硬写,初始化常量遇到了这样的问题,如 Rust 中:

let a = if <slow operation A> {
    1
} else if <slow operation B> {
    2
} else {
    3
};

(注:Rust 不带mut默认是常量)

没有这个功能的话,a 就得声明成 mutable ,然后在条件分支里面改,或者用一长串?:?:。 用 C++的时候是用一个临时的 lambda ,在条件里 return 。

const int i = [&]() {
    if (<slow operation A>)
        return 1;
    else if (<slow operation A>)
        return 2;
    else
        return 3;
}();

看 V 站经常有人说 C#功能大杂烩,有没有好一点的办法?

1431 次点击
所在节点    C#
5 条回复
nikenidage1
311 天前
没有 if 赋值这样,但是你可以模式匹配,觉得如何?

var tempInFahrenheit = 10;
var tempText = tempInFahrenheit switch
{
(> 32) and (< 212) => "liquid",
< 32 => "solid",
> 212 => "gas",
32 => "solid/liquid transition",
212 => "liquid / gas transition",
};
geelaw
311 天前
需要 if 而不是 ?: 的本质原因应该是计算 true/false 分支必须用多条语句完成,而不是条件的快慢。

C# 里也可以用匿名委托、lambda 表达式像 C++ 那样实现复杂初始化 readonly 局部变量,但性能堪忧。
nikenidage1
311 天前
LaTero
311 天前
@nikenidage1
@geelaw
谢谢,用 pattern matching 大部分时候是可以的,但是假如两个函数 f(), g()都很慢,用 if else 可以短路,pattern matching 的话似乎必须要都求值然后放进 tuple 里才能 match. 不过好像也可以用 case guard,
```
0 switch
{
0 when f() => 1,
0 when g() => 2,
_ => 3,
};
```
虽然有点丑。
LaTero
311 天前
@nikenidage1 想了一下,可以反向匹配,用 true 去匹配 f()和 g(),不知道有没有短路求值的效果。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/953465

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX