从可选列表中删除空值后的 C# 结果类型列表

C# result type of list after removing nulls from a list of optionals

假设我有一个 C# 选项列表(此处称为 x),并且我通过删除空值创建了一个新列表(此处新列表称为 y

static void Main()
{
    var x = new List<long?> { 7, 8, 9, null, 10, null, 11 };
    var y = x.Where(e => e != null);
    Console.WriteLine("{0}", y);
}

y的类型推断为List<long?>。获得 List<long> 类型的惯用方法是什么?显式解包还是显式转换?或者有更清洁的方法吗?

在我处理的实际实现中,值以可选列表的形式出现,我需要将这些列表转换为下游集合,所以 "passing the buck" 到后续操作不是我想要的去做(虽然我可以在代码的后面做很多很多空检查......yuk)。我真的很想有一个长列表变量。在 C# 中如何最好地思考和处理这个问题?

我会检查 HasValue 属性 和 select Value

你可以试试这个:

var y = x.Where(e => e.HasValue).Select(e => e.Value);

有无.ToList()

只需使用 x.OfType<long>().ToList() - 这将过滤掉所有空值,结果类型将为 List<long>

使用 Select 的显式转换可以完成这项工作:

        var x = new List<long?> { 7, 8, 9, null, 10, null, 11 };
        var y = x.Where(e => e != null);
        Console.WriteLine("{0}", y);
        IEnumerable<long> z = x.Where(e => e != null).Select(e => (long)e);
        Console.WriteLine("{0}", z);

我认为最好是创建自己的扩展方法:

public static class Extensions
{
    public static IEnumerable<T> RemoveNullsAndConvert<T>(this IEnumerable<T?> source)
        where T : struct
    {
        return from x in source where x != null select x.Value;
    }
}

然后简单地使用

var y = x.RemoveNullsAndConvert();

当然你可以为方法使用更短的名称,并且实现不一定必须使用 LINQ - 例如它可以是 C# 迭代器:

public static class Extensions
{
    public static IEnumerable<T> RemoveNullsAndConvert<T>(this IEnumerable<T?> source)
        where T : struct
    {
        foreach (var x in source)
            if (x != null) yield return x.Value;
    }
}