【问题标题】:Why am I seeing different behavior between 'if' and ternary with linq?为什么我在 linq 中看到“if”和三元之间的不同行为?
【发布时间】:2012-07-24 02:58:01
【问题描述】:

我有一种情况,我使用三元运算符来确定 IEnumerable 是否为空,但它的行为与我预期的不同。

如果我这样做:

var children = clickedItem.Children != null ? clickedItem.Children.ToArray() : null;

然后我收到一个参数空异常(“源不能为空”),这表明尽管进行了空检查,但仍发生了 .ToArray()

如果我将其更改为(看似)相同的逻辑:

var children = clickedItem.Children;
if (children != null) children = children.ToArray();

然后错误消失。三元运算符不会像我一直想象的那样短路吗?

编辑根据问题:

是的,我是第一次设置孩子,但不是第二次:

public IEnumerable<AlbumOrTrack> Children
 {
    get
    {
        if (_children == null)
        {
            _children = _dataAccess.GetChildren(this);
        }
        return _children;
    }
 }

异常发生在 .ToArray() 调用中。我得到了

// Exceptions:
//   System.ArgumentNullException:
//     source is null.

(来自元数据)

【问题讨论】:

  • 你在哪里得到异常?
  • 你有clickedItem.Children的实现吗?

标签: c# if-statement ternary-operator


【解决方案1】:

一个区别是,在第二种形式中,您只计算表达式clickedItem.Children一次

想象一下,如果 Children 属性被实现为:

public IEnumerable<Child> Children
{
    get
    {
        var ret = children;
        // Mwahahaha! A getter with side-effects. They'll never expect that!
        children = null; 
        return ret;
    }
}

(当然,也可能只是竞争条件。)

【讨论】:

  • ...你是对的。照常。我确实有竞争条件,我需要使用克隆而不是将 _children 设置为空。谢谢!
猜你喜欢
  • 1970-01-01
  • 2018-02-22
  • 1970-01-01
  • 1970-01-01
  • 2018-10-15
  • 1970-01-01
  • 2022-01-25
  • 1970-01-01
  • 2012-11-26
相关资源
最近更新 更多