【问题标题】:Is there a conditional ternary operator in VB.NET?VB.NET 中有条件三元运算符吗?
【发布时间】:2010-10-09 06:03:26
【问题描述】:

在 Perl(和其他语言)中,条件三元运算符可以这样表示:

my $foo = $bar == $buz ? $cat : $dog;

VB.NET中有类似的运算符吗?

【问题讨论】:

  • 三元运算符是任何需要三个操作数的运算符,就像二元运算符需要两个操作数而一元运算符需要一个操作数一样。 ?: 运算符是三元运算符的具体示例,而不是定义。

标签: vb.net operators conditional-operator short-circuiting


【解决方案1】:

取决于版本。 VB.NET 2008 中的If 运算符是三元运算符(以及空合并运算符)。这是刚刚推出的,在 2008 年之前这是不可用的。以下是更多信息:Visual Basic If announcement

例子:

Dim foo as String = If(bar = buz, cat, dog)

[编辑]

在 2008 年之前,它是 IIf,其工作方式与上述 If 运算符几乎相同。

例子:

Dim foo as String = IIf(bar = buz, cat, dog)

【讨论】:

  • 在 2008 年之前是 IIf,它的工作原理与您链接中描述的 If 运算符几乎相同。
  • ...重要的区别是 Iif() 作为一个函数,总是同时评估结果和替代,而新的 If 只评估其中一个。
  • 这是什么意思?如果(条件,真部分,假部分)。我可以仪式吗?
  • 我是个 C 大佬,但我发现这种语法比传统的三元运算符更简洁。
  • 另一个重要区别:Iif 总是返回 Object 类型的对象,而 If(bool, obj, obj) 允许使用严格的选项进行类型检查。 (Dim var As Integer = Iif(true, 1, 2) 不会在使用 strict on 选项进行编译,因为您可以很容易地编写 Dim var As Integer = Iif(true, new Object(), new Object())。不过您可以编写 Dim var As Integer = If(true, 1, 2) 并使用 strict 选项,因为它会检查返回的类型。)
【解决方案2】:

iif 在 VB 中一直可用,即使在 VB6 中也是如此。

Dim foo as String = iif(bar = buz, cat, dog)

因此,它不是真正的运算符,而是 Microsoft.VisualBasic 命名空间中的一个函数。

【讨论】:

  • Iif 仅接近三元运算符 - 这意味着您不能在使用 If Then Else(或三元运算符)的每种情况下都使用它。例如,Value = Iif(1 = 1, 0, 1/0) 会爆炸,但 Value = If(1 = 1, 0, 1/0) 不会...
  • VB 不支持短路评估(除了 AndAlso 运算符),因此 VB 程序员并不真正期望他们可以安全地评估一半的操作。但要指出的是,iif 也是一个 hack 函数,它是为了向后兼容而引入的,否则它将是一个真正的运算符。
  • 很高兴对所有 VB 程序员进行分类 ;-) 还有 IsNot 和 OrElse 的快捷方式,所以 VB 确实支持短路评估。
  • Iif 是一个常规方法调用并评估所有参数。它不是三元的。硒dotnetslackers.com/VB_NET/…
  • 正如我所说,它不是真正的运算符,而且 vb6 不支持短路评估,因此它总是在线评估所有操作。
【解决方案3】:

If() 是最接近的等价物,但如果您设置了Option Strict off请注意隐式 转换。

例如,如果您不小心,您可能会尝试以下操作:

Dim foo As Integer? = If(someTrueExpression, Nothing, 2)

会给foo一个0的值!

我认为在 C# 中等效的 ? 运算符会导致编译失败。

【讨论】:

  • 为了完整起见,编写该表达式的更好方法是Dim foo As Integer? = If( someTrueExpression, New Integer?, 2)
  • 请注意,Option Strict On 也会发生这种情况。原因是VB.NET中的Nothing等价于C#的default(T)而不是null
  • 对于任何对Integer? 感到困惑的人,这意味着它可以为空 - 请参阅stackoverflow.com/questions/3628757/make-an-integer-null
  • 对于任何陷入可空类型隐式转换的人 - 请参阅 this answer as to whythis answer for a workaround 在返回之前强制转换参数 (CType(Nothing, DateTime?)。
【解决方案4】:

为了记录,这里是 IfIIf 之间的区别:

IIf(条件,真部分,假部分)

  • 这是旧的 VB6/VBA 函数
  • 该函数总是返回一个 Object 类型,因此如果您想使用所选对象的方法或属性,您必须使用 DirectCast 或 CType 或 Convert.* 函数将其重新转换为其原始类型
  • 因此,如果 true-part 和 false-part 的类型不同,则没有任何关系,结果无论如何只是一个对象

如果(条件,真部分,假部分)

  • 这是新的 VB.NET 函数
  • 结果类型是所选部分的类型,true-part 或 false-part
  • 这不起作用,如果打开了严格模式并且这两个部分是不同的类型。在严格模式下,它们必须是相同的类型,否则你会得到一个异常
  • 如果您确实需要两个不同类型的部分,请关闭严格模式(或使用 IIf)
  • 到目前为止,如果严格模式允许不同类型的对象但从相同的基类继承或实现相同的接口,我还没有尝试过。 Microsoft 文档对此问题没有太大帮助。也许这里有人知道。

【讨论】:

    【解决方案5】:
    If(<expression>, <expressionIfNothing>)
    

    如果 &lt;expression&gt; 的计算结果为非 Nothing 的引用或 Nullable 值,则函数返回该值。否则,计算并返回&lt;expressionIfNothing&gt;

    直接从 Intellisense 复制。

    【讨论】:

      猜你喜欢
      • 2022-01-06
      • 2017-02-08
      相关资源
      最近更新 更多