为什么我看到'if'和三元与linq之间的不同行为?

时间:2012-07-25 15:54:54

标签: c# if-statement ternary-operator

我有一种情况,我使用三元运算符来确定IEnumerable是否为null,并且它的行为不像我期望的那样。

如果我这样做:

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

然后我收到一个参数null异常(" source不能为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.

(来自元数据)

1 个答案:

答案 0 :(得分:3)

一个区别是,在第二种形式中,您只评估表达式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;
    }
}

(当然,它可能只是一种竞争条件。)