【发布时间】:2021-03-08 10:10:47
【问题描述】:
所以我想知道您是否可以创建一个扩展方法,将.Where() 和.Select() 的功能结合起来,用于过滤掉列表的空值并使类型与可空引用类型保持一致的特殊情况。这意味着如果我得到一个string?[],它将过滤掉所有null 值并返回一个不带可为空字符串的IEnumerable<string>。
但是,当我尝试过滤出如下所示的可空元组时,我收到编译器错误,即预期为不可空元组类型。 为什么此解决方案适用于所有常规类型但不适用于元组,我如何更改我的扩展方法以也适用于元组。
扩展方法:
public static IEnumerable<TResult> SelectNotNull<TSource, TResult>
(this IEnumerable<TSource> enumerable, Func<TSource, TResult?> selector)
{
foreach (var item in enumerable)
if (selector(item) is { } result)
yield return result;
}
产生编译器错误的示例代码:
(string?, int)[] arr = Array.Empty<(string?, int)>();
static (string, int)? Selector((string?, int) x)
{
return x.Item1 != null ? x : null;
}
arr.SelectNotNull<(string?, int), (string, int)>(Selector);
【问题讨论】:
-
(string?, int)不是可以为空的元组,也许你打算这样做(string?, int)? -
请注意,这不适用于所有值类型,不仅仅是元组。
-
@RandRandom 你是对的,
(string?, int)不是可空元组,但是过滤方法“选择器”产生可空元组(string, int)?,然后产生编译器错误。 -
@Sweeper 是的,我在验证它是否影响所有值类型时似乎犯了一个错误,这就是为什么我认为它只会导致元组出现问题。
-
c# 中没有“可空引用类型”之类的东西 - 这就是每个引用类型都可以为空的区别,即使使用 c# 8 和“新" 特征类型
string?不是Nullable<string>它只是“魔术”,编译器会警告你尝试将 null 分配给你没有明确声明它可能为 null 的东西,例如。string str = null;是完全有效的 c# 代码,您不必编写string? str = null;但如果您启用了 c#8 功能,您将收到第一个警告
标签: c# generics tuples nullable