【问题标题】:Conditional ternary with method call to db带有对 db 的方法调用的条件三元
【发布时间】:2015-08-11 23:23:51
【问题描述】:

所以过去几年我一直潜伏在这里,终于来到了我在这里没有找到现有答案的情况。这个问题本身很简单。


假设以下语句(无特定语言语法):

var result = fetchFromDb() == null ? defaultValue : fetchFromDb().property;

我想知道的是:Java 或 C# 中的编译器是否有办法优化此语句,或者真的会有两次对 fetchFromDb() 方法的调用,这意味着两个数据库访问调用、两个执行计划等等?

我已经在 J​​ava 中对此进行了测试,发现该方法被调用了两次,但我不知道最终在后台缓存或类似的东西。

那么:使用带有方法的三元条件是一种不好的做法吗?有没有办法缓存与内联比较的值以保持这种风格的美感?

【问题讨论】:

  • var 结果 = fetchFromDbSupplyingDefaultValue(defaultValue);
  • 除非它是一个众所周知的功能,否则它不会得到优化。
  • 人们通常认为三元运算符是if 的替代品,其实不然。虽然这种风格在许多情况下可能很有吸引力,但尝试将所有 if 强制用于三元运算符(从 Java/C# 的角度来看)是没有意义的。

标签: java c# performance conditional-operator method-call


【解决方案1】:

是的,它永远是两个电话。事实上,在第一次调用和第二次调用之间,fetchFromDb() 的结果可能会发生变化。编译器无法预测值的变化,除非它是众所周知的确定性function。确定性是这里的关键词。即使那样,也可能没有针对此类事情的编译器优化。

在方法中使用三元条件本身并不是坏习惯,但它比简单的 if 语句可读性差。

保证单个调用的唯一方法是编写单个调用。

var result;
var fetchResult = fetchFromDb();
if (fetchResult == null) {
    result = defaultValue;
} else {
    result = result.property;
}

或者如果你坚持使用三元组

var fetchResult = fetchFromDb()
var result = (fetchResult == null) ? defaultValue : result.property;

我真的认为这比三元更清晰。将代码放在一行并不能推断出漂亮的代码。

【讨论】:

  • 感谢您解决此问题。尽管如此,在三元条件下有一些 value 变量还是很好的,就像你在 C# 中使用自定义属性设置器一样......当然,数据库可以在两个调用之间改变,但我为什么要关心那改变?会让比较毫无意义。
【解决方案2】:

其实

var result = fetchFromDb() == null ? defaultValue : fetchFromDb().property;

将在else 案例中进行两次调用。避免双重调用:

var fetch = fetchFromDb();
var result = fetch != null ? fetch.property : defaultValue;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-26
    • 1970-01-01
    • 1970-01-01
    • 2014-09-07
    • 1970-01-01
    • 2020-03-17
    • 1970-01-01
    • 2012-03-16
    相关资源
    最近更新 更多