【问题标题】:Avoiding nesting if/else if as well as avoiding InvalidOperationException at the same time in a conditional statement避免嵌套 if/else if 以及在条件语句中同时避免 InvalidOperationException
【发布时间】:2019-05-13 12:00:13
【问题描述】:

我遇到了这个巨大的方法,我有很多 if else 类型的语句

else if (ptName == "Missile" ||
         ptName == "Telephone" ||
        (ptName.StartsWith("Car") && gasTank.ValueFloat1.Value < 90))
        {
         foo_1 = "some_string";
        }

不幸的是,这段代码并不完全正确,因为变量 gasTank 仅在 ptName 以字符串“Car”开头的情况下定义。因此,在运行时我得到了

InvalidOperationException 发生:Null 对象必须有值。

这可以通过嵌套 if 和 else if 以及重复条件 ptName.StartsWith("Car") 来解决,尽管这是非常不可取的。

将方法拆分为多个小方法或在每个条件后添加 return 不是一种选择,因为方法的 return 是各种 foo_i 的串联。

提前谢谢你。

【问题讨论】:

  • 通常 gasTank 不会被测试,除非 StartsWith("Car") 是真的.. 除非你有东西以 car 开头并且没有 gasTanks
  • C# 中的布尔运算符是短路的,如果左边的操作数足以获得值,则不应计算右边的操作数。您可能会遇到ptName Car 开头但gasTank 中没有ValueFloat1 的情况。

标签: c# anti-patterns


【解决方案1】:

条件

ptName.StartsWith("Car")

应该变成

ptName?.StartsWith("Car") ?? false

这会让你摆脱null的价值。

如果你使用的是低于 6 的 C# 版本,那么你应该使用:

ptNAme == null ? false : ptName.StartsWith("Car")

另一个更新:

(gasTank.ValueFloat1?.Value ?? 0) < 90

(gasTank.ValueFloat1.HasValue ? gasTank.ValueFloat1.Value : 0) < 90

【讨论】:

  • 非常感谢,我想我离这个越来越近了,虽然我明白了使用 后不需要 : 的逻辑吗?运算符?
  • @user94028 好吧,如果它是三元运算符,你会是对的,但这里? 的含义不同,请参见:Safe Navigation Operator。如果答案对您有帮助,请勾选左侧的绿色复选标记以接受它
  • 问题是,如果我进行此更改,我会收到一个语法错误,它需要来自您的链接的 :,看起来我没有使用 C# 版本是允许的,因为这是 C# 3.0
  • @user94028 更新答案
  • 不幸的是,我仍然遇到同样的错误。 ptName 是一个变量,其值从不为空,它可能只是“Car”以外的其他东西,无论如何,第二个条件 gasTank.ValueFloat1.Value
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多