带有默认值的 C# LINQ SelectMany

Den*_*er9 5 c# linq extension-methods func

我正在寻找一种优雅的解决方案,将集合中的子集合聚合为一个大集合。我的问题是某些子集合何时可能为空。

例如:

var aggregatedChildCollection = parentCollection.SelectMany(x=> x.ChildCollection);
Run Code Online (Sandbox Code Playgroud)

如果任何子集合对象为空,这将引发异常。一些替代方案是:

// option 1
var aggregatedChildCollection = parentCollection
    .Where(x=>x.ChildCollection != null)
    .SelectMany(x => x.ChildCollection);

// option 2
var aggregatedChildCollection = parentCollection
    .SelectMany(x => x.ChildCollection ?? new TypeOfChildCollection[0]);
Run Code Online (Sandbox Code Playgroud)

两者都可以工作,但我正在对父级上的相当多的子集合进行某种操作,并且它变得有点令人生厌。

我想要的是创建一个扩展方法来检查集合是否为空,如果是,选项 2 会做什么 - 添加一个空数组。但是我对 Func 的理解并没有达到我知道如何编写这种扩展方法的地步。我知道我想要的语法是这样的:

var aggregatedChildCollection = parentCollection.SelectManyIgnoringNull(x => x.ChildCollection);
Run Code Online (Sandbox Code Playgroud)

是否有一个简单的扩展方法可以实现这一点?

Dav*_*idG 4

您可以使用自定义扩展方法:

public static IEnumerable<TResult> SelectManyIgnoringNull<TSource, TResult>(
    this IEnumerable<TSource> source, 
    Func<TSource, IEnumerable<TResult>> selector)
{
    return source.Select(selector)
        .Where(e => e != null)
        .SelectMany(e => e);
}
Run Code Online (Sandbox Code Playgroud)

并像这样使用:

var aggregatedChildCollection = parentCollection
    .SelectManyIgnoringNull(x => x.ChildCollection);
Run Code Online (Sandbox Code Playgroud)