Linq:IEnumerable上的扩展方法,用于在执行选择时自动执行空值检查

ebu*_*bug 5 c# linq c#-5.0

当执行一个Selecton IEnumerable我相信检查空引用是一个好习惯,所以我经常Where在我之前有Select这样的:

someEnumerable.Where(x => x != null).Select(x => x.SomeProperty);
Run Code Online (Sandbox Code Playgroud)

访问子属性时,这会变得更加复杂:

someEnumerable.Where(x => x != null && x.SomeProperty != null).Select(x => x.SomeProperty.SomeOtherProperty);
Run Code Online (Sandbox Code Playgroud)

要遵循这种模式,我需要进行一次调用Where.我想创建一个扩展方法IEnumerable,根据引用的内容自动执行这样的空检查Select.像这样:

someEnumerable.SelectWithNullCheck(x => x.SomeProperty);
someEnumerable.SelectWithNullCheck(x => x.SomeProperty.SomeOtherProperty);
Run Code Online (Sandbox Code Playgroud)

可以这样做吗?是fx.selector在创建扩展方法时可以从参数中检索选定的属性吗?

public static IEnumerable<TResult> SelectWithNullCheck<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
{
    return source.Where(THIS IS WHERE THE AUTOMATIC NULL-CHECKS HAPPEN).Select(selector);
}
Run Code Online (Sandbox Code Playgroud)

编辑:我在.NET Framework 4.5中使用C#5.0

Gil*_*een 4

当您使用 C# 5.0 时,您可以按以下方式编写扩展方法:

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

在投影之前和之后(Select call)应用检查以确保结果不为空。那么用法将是:

someEnumerable.SelectWithNullCheck(x => x.SomeProperty)
              .SelectWithNullCheck(y => y.SomeOtherProperty);
Run Code Online (Sandbox Code Playgroud)

请注意,每次调用中的项目类型都不同。


如果你确实想要类似这样的:

someEnumerable.SelectWithNullCheck(x => x.SomeProperty.SomeOtherProperty);
Run Code Online (Sandbox Code Playgroud)

然后您需要遵循 @Treziac 的建议并使用?.运算符(在 C# 6.0 中引入),然后过滤掉 null:

public static IEnumerable<TResult> SelectWithNullCheck<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
{
    return source.Select(selector).Where( x=> x != null);
}

someEnumerable.SelectWithNullCheck(x => x?.SomeProperty?.SomeOtherProperty);
Run Code Online (Sandbox Code Playgroud)