在C#中如何测试“惰性加载”的空IEnumerable?

7

我已经简化了一段延迟执行的代码,但是怎么才能在不使用try/catch的情况下检查以下内容不为空/空字符串呢?

    string[] nullCollection = null;
    IEnumerable<string> ienumerable = new[] { nullCollection }.SelectMany(a => a);

    bool isnull = ienumerable == null; //returns false
    bool isany = ienumerable.Any(); //throws an exception

@MrinalKamboj,这是一个NullReferenceException的抛出,因为SelectManyIterator被调用时使用了空元素。 - RB.
@RB。那就有点棘手了,我之前提到的任何一点都不适用。 - Mrinal Kamboj
4个回答

3
你不能这样做,因为这等同于问“如何在不调用方法的情况下判断该方法是否会引发NullReferenceException?”。如果没有其他线索,唯一的方法就是实际调用这些方法并观察结果。枚举IEnumerable只是在其枚举器上调用一堆MoveNext调用,任何这样的调用都可能引发任何异常。

3
只需使您的Lambda更能够容忍空条目即可:
IEnumerable<string> ienumerable = new[] { nullCollection }
    .SelectMany(a => a ?? Enumerable.Empty<string>());

bool isany = ienumerable.Any(); // Sets isany to 'false'

这很好,但如果我只传递了一个 IEnumerable<string> 参数,我想我就卡住了... - maxp
@maxp 是的 - ienumerable 的构造存在根本性问题。我认为没有任何修复方法。 - RB.

2
您可以检查枚举器的当前项是否为空。
string[] nullCollection = null;
IEnumerable<string> ienumerable = new[] { nullCollection }.SelectMany(a => a);

bool isnull = ienumerable.GetEnumerator().Current == null;
if (!isnull)
{
    bool isany = ienumerable.Any();
}

1
这样做不行 - 当你调用 MoveNext() 进行迭代时,如果遇到 null 元素,程序将会崩溃。最终,投影函数将对每个元素进行评估,并在使用 null 值调用它时导致崩溃 - 我认为无法避免这种情况。 - RB.
2
@RB。没有MoveNext(),就没有Current :)。回到原点了吗? - Mrinal Kamboj
3
这个回答是相当不正确的 - 在访问MoveNext之前访问Current会产生未定义的行为 - 很可能在这里它总是返回null - Ivan Stoev
1
@IvanStoev 我说了那个 :) - Mrinal Kamboj
2
@MrinalKamboj 是的 - 我想我们都以稍微不同的方式表达了同样的事情 :) - RB.

0

由于Linq方法是IEnumerable的扩展方法,因此您可以进一步包装这些扩展:使用扩展方法,接收扩展的对象可以为null。

    public static IEnumerable<TResult> SafeSelectMany<T, TCollection, TResult>(
            this IEnumerable<T> source, 
            Func<T, IEnumerable<TCollection>> collectionSelector, 
            Func<T, TCollection, TResult> resultSelector)
    {
        if (source == null)
        {
            return null;
        }
        IEnumerable<TResult> result = source.SelectMany(collectionSelector, resultSelector);
        return result;
    }

您也可以返回一个空的List<TResult>而不是null,以处理 source==null 的情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接