【问题标题】:Short circuit with TryParse() and out variable reliable?TryParse() 短路和输出变量可靠吗?
【发布时间】:2018-10-22 08:42:13
【问题描述】:

这个话题讨论过很多次了,很清楚:Is relying on && short-circuiting safe in .NET?

如果在if子句的右侧部分使用out参数时短路也可靠,我找不到明确的答案:

int foo;
....
if ( false == Int32.TryParse( bar, out foo ) || 0 == foo )

当我尝试这段代码时,它就可以工作了。但是我有点担心这种行为是否可靠,因为我不知道编译器是如何翻译代码并访问foo的。

我的问题:

foo 的访问是否真的在之后 TryParse 完成,它会考虑任何更改的值,或者编译器有时可以读取之前 TryParse [由于一些优化] 因此我不能依赖此代码。

【问题讨论】:

  • 除非 C# 编译器有错误,否则它会工作,如果变量在分配之前被访问,那么编译器会抱怨它。
  • @Steve 第二个条件非常必要什么时候可以成功解析。

标签: c# conditional-statements


【解决方案1】:

对 foo 的访问真的是在 TryParse 之后完成的吗? 考虑任何更改的值

是的,就是这样。

或者编译器有时可以在 TryParse 之前读取值 [因为 一些优化],因此我不能依赖这段代码。

不,在调用Int32.TryParse 之前它不会读取foo;一个是逻辑或将始终评估左侧,在必要时评估右侧。第二,它不会首先评估右侧,因为foo 变量在那个时候没有初始化,这会导致编译错误(假设它是一个局部变量)。

【讨论】:

  • 重点是foo 是一个类成员,因此编译器从不警告未初始化的变量——它会改变什么吗?
  • @AlBundy 不会改变表达式的计算方式。
【解决方案2】:

您可以使用 C# 中的新语言功能来验证它是否有效:

if (!int.TryParse("0", out int foo) || foo == 0)
{
    //foo == 0 or the tryparse failed
    //foo still exists here though, so if it fails, it will still == 0
}

您可以看到foo 的声明发生在int.TryParse 调用中,如果首先评估foo == 0,则不会发生这种情况。这是 C# 7 及更高版本中的合法语法。真的,这是所有语法糖:

int foo = 0   
if (!int.TryParse("0", out foo) || foo == 0)
{
    //foo == 0 or the tryparse failed
}

【讨论】:

  • 我喜欢这个解释,但不幸的是,由于使用了框架,我坚持使用旧的 C# 版本。
  • @AlBundy 框架版本和语言版本是独立的,你可以使用 C# 7.1 并根据需要针对 .NET 2.0 进行编译。
  • :-) - 我正在为NinjaTrader 7 开发,我必须使用他们提供的 C# 编译器:-((
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-10
  • 1970-01-01
  • 2021-02-09
  • 2021-08-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多