【问题标题】:How to avoid evaluation of all of 'iif' expression?如何避免评估所有“iif”表达式?
【发布时间】:2012-11-21 13:22:06
【问题描述】:

是 VB.NET 2005,有没有办法在尝试将空字符串转换为整数时不抛出 invalid cast exception 来执行以下操作?

Dim strInput As String = String.Empty
Dim intResult As Integer = IIf(IsNumeric(strInput), CInt(strInput), 100)

【问题讨论】:

  • 我会说你的 IsNumeric 方法应该为空字符串返回 false。但是你为什么要检查strInput 然后使用str
  • 你不能 - IIf 不是一个表达式,而是一个函数,所以它必须在执行之前先计算所有参数。
  • @JoelEtherton:对不起,只是一个错字。它确实返回 false,但我认为它会引发异常,因为它无论如何都会尝试评估整个表达式。

标签: .net vb.net casting lazy-evaluation iif


【解决方案1】:

VB.NET 现在有了真正的三元运算符(2008 年后)

Dim intResult = If(IsNumeric(strInput), CInt(strInput), 100)

这与 IIF 不同,因为它使用短路评估。
如果测试表达式的计算结果为真,则 FalsePart 将被忽略,反之亦然

正如 Marek Kembrowsky 先生在其评论中所说,IIF 是一个函数,其参数在传入之前都经过评估,而 IF(作为三元运算符)是 VB 编译器的附加功能。

但是,当我在 VB.NET 中编程时,我不喜欢使用 Microsoft.VisualBasic 兼容命名空间提供的快捷方式。该框架提供了更好的解决方案,例如 TryParse 方法集。如果输入字符串超过 Integer.MaxValue,您的示例将失败。

更好的方法可能是

Dim d As decimal
if Not Decimal.TryParse(strInput, d)  then d = 100

或者,如果你有一个浮点 string(?好吧好吧,你明白我的意思)

Dim d As Double
if Not Double.TryParse(strInput, d)  then d = 100

【讨论】:

  • 您对使用 VisualBasic 命名空间的主要反对意见是什么?
  • 主要是个人喜好,想和VB6断绝关系,然后麻烦分发Microsoft.VisualBasic.dll(实际上我从1.1的时候就没有查过,也许没必要分发它)
【解决方案2】:

If 解决方案将起作用......但 IsNumeric() 不是正确的检查。如果 strInput 是一个数字但超过 integer.maxvalue 怎么办?改用 TryParse 效果更好。

Dim i As Integer
If Not Integer.TryParse("1234567890", i) Then i = 100

Dim j As Integer = If(Integer.TryParse("123456789", Nothing), Integer.Parse("123456789"), 100)

【讨论】:

  • +1 好点,但第二个例子应该避免(在我看来)
  • CJ7:整数是正确的类型(对于整数)。在我的示例中,我仅将 StrInput 替换为“1234567890”。 @Steve:OP的原始代码是单行的,所以也许他更喜欢这种风格。
  • 这不是单行样式,这是因为您强制对输入字符串进行双重评估(如果为真)。
  • 我的意思是,如果设想输入可能超过Integer.MaxValue,那么程序员应该首先使用Long而不是Integer
  • 问题不在于程序员希望输入是什么,而在于用户给他什么。地狱!如果没有这些该死的用户,编程可能会非常有趣...... ;) 通过使用 Isnumeric(),您已经承认,输入字符串可能是所有内容(如“apple”、“foo”)。如果它可以是“Foo”,它也可以是数字,但不适合 Int 甚至 Long。而且我们通常不想到处使用 BigInteger,对吗?
【解决方案3】:

解决问题的一种方法是:

Dim strInput As String = String.Empty
Dim intResult As Integer = IIf(IsNumeric(strInput), strInput, 100)

这样转换是隐式完成的,不会出现任何无效转换异常。

【讨论】:

  • @igrimpe: 一个已经通过IsNumeric 测试的字符串
  • 测试这个:“123456789123456789”。它是否通过 IsNumeric?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-03
  • 1970-01-01
  • 2014-06-13
  • 2011-04-03
  • 2014-07-06
相关资源
最近更新 更多