在C#中的Iif等效功能

85

在C#中是否有类似于VBA的IIf函数或类似的快捷方式?


5
我认为您的意思是“捷径”而不是“短路”(它在布尔运算中有特定的含义)- 我理解得对吗? - Blorgbeard
7个回答

127

C#有类似其他C风格语言的三元运算符?。然而,这与IIf()并不完全等价;有两个重要的区别。

为了解释第一个区别,这个IIf()调用的false-part参数会导致DivideByZeroException,即使布尔参数是True

IIf(true, 1, 1/0)

IIf()是一个函数,和所有函数一样,在调用之前必须评估所有参数。换句话说,IIf()不会在传统意义上进行短路计算。另一方面,这个三元表达式可以进行短路计算,因此非常好用:

(true)?1:1/0;

另一个区别是 IIf() 不具备类型安全性。它接受和返回类型为 Object 的参数。三元运算符 类型安全的。它使用类型推断来知道它正在处理的类型。请注意,您可以通过自己的通用 IIF(Of T)() 实现轻松解决这个问题,但开箱即用的方式不是这样的。
如果你真的想要在 C# 中使用 IIf(),你可以拥有它:
object IIf(bool expression, object truePart, object falsePart) 
{return expression?truePart:falsePart;}

或者一个通用/类型安全的实现:
T IIf<T>(bool expression, T truePart, T falsePart) 
{return expression?truePart:falsePart;}

另一方面,如果您想在VB中使用三元运算符,Visual Studio 2008及更高版本提供了一个新的If() 运算符,它的工作方式类似于C#的三元运算符。它使用类型推断来知道它返回的是什么,并且它确实是一个运算符而不是函数。这意味着没有预先评估表达式的问题,即使它具有函数语义。


3
VB9支持真正的三目运算符。如果(SomeBool, MessageBox.Show("True"), MessageBox.Show("False"))如此所示:http://community.bartdesmet.net/blogs/bart/archive/2007/08/31/visual-basic-9-0-the-if-ternary-operator.aspx - snarf
1
我在最后一段提到了它,但问题特别涉及到IIf()。 - Joel Coehoorn

67

VB.NET:

If(someBool, "true", "false")

C#
someBool ? "true" : "false";

2
虽然对于简单表达式而言,这是正确的,但如果在替代表达式中存在副作用,那么这两种形式并不完全等价。Iif(t,foo(),bar())将调用foo()和bar(),而t ? Foo() : bar()将仅调用foo()或bar()中的一个,而不是同时调用两个。有关更多信息,请参见Joel Coehoorn对此问题的回答。 - Greg Hewgill
1
更新答案,使用VB.NET的“If”函数代替“IIf”,以使两个代码块等效。 - Kevin Pang

13

三元运算符

bool a = true;

string b = a ? "if_true" : "if_false";

我会在那里添加一条注释,即字符串 b = (a?"asdf":"dsrs")。这样可以更好地理解该事物的工作原理,并且可以看到它不像(string b=a)?"sdf":"sdsdf"那样奇怪和毫无意义。 - barlop

10

另一个有用的运算符是 coalesce 运算符 ??:

VB:

Return Iif( s IsNot Nothing, s, "My Default Value" )

C#:

return s ?? "My Default Value";

6

1

这是三元运算符?

string newString = i == 1 ? "i is one" : "i is not one";

0

它的限制在于你不能把语句放在里面。你只能放置值(或者返回/评估为值的东西),以进行返回。

这个有效('a' 是类 Blah 中的静态整数)

Blah.a=Blah.a<5?1:8;

(圆括号隐含在等号和问号之间)。

这个不起作用。

Blah.a = Blah.a < 4 ? Console.WriteLine("asdf") : Console.WriteLine("34er");
or
Blah.a = Blah.a < 4 ? MessageBox.Show("asdf") : MessageBox.Show("34er");

所以你只能使用C#三元运算符来返回值。所以它并不完全像if的缩写形式。Javascript和其他一些语言允许在其中放置语句。


是的,因为它正在设置一个值,而不是调用一个方法。不过你可以使用“Action”来实现你想要的功能。 - Kieran Foot
@KieranFoot WriteLine是一种方法。虽然已经有一段时间了,但如果iif或三元运算符允许您在其中放置返回值,例如Blah.a = Blah.a < 4 ? Console.WriteLine("asdf"); return 1: Console.WriteLine("34er") ; return 2;,那么如果它允许这样做,它就可以工作,但显然它不行。是的,它仍然设置一个值,而且它没有调用任何新方法。 - barlop
你可以很容易地将其变成内联,如果它执行我所说的两个操作之一。 - Kieran Foot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接