1

我有一种情况,我使用三元运算符来确定 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.

(来自元数据)

4

1 回答 1

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;
    }
}

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

于 2012-07-25T15:59:20.313 回答