使用LINQ组合两个可能为空的列表

11
我有两个列表:
    var myIds = new List<int>()
        {
            1, 2, 3
        };

    var yourIds = new List<int>()
        {
            2, 3, 4
        };

这两个列表可以合并为一个,像这样:

myIds.Union(yourIds)
.Select(x => new 
             { 
                 Id = x,
                 Mine = myIds.Contains(x), 
                 Yours = yourIds.Contains(x)
             });

新列表将如下所示:
Id    Mine     Yours
---------------------
1      T         F
2      T         T
3      T         T
4      F         T

当列表包含元素时,这很有效。但是,如果列表有可能为null,我该如何处理null列表?


1
你的意思是 myIds 或者 yourIds 是 null 吗?还是它们包含可以为 null 的元素?(后者在这种情况下不可能) - Sriram Sakthivel
两个列表都有可能为空。但是,它们不会包含任何空元素。 - navig8tr
昨天另一个用户甚至在代码中执行了Union操作,问了完全相同的问题。这是上课的作业吗? - Scott Chamberlain
我可以回答这个问题,但说实话,它不如检查 null 值好用。如果你真的需要避免 null 检查,可以创建一个帮助方法来为你执行 null 检查并返回 Enumerable.Empty<int>() - Sriram Sakthivel
是的,我认为检查每个列表是否为空同样容易。 - navig8tr
1个回答

29
如果列表可能为null,则必须检查null。您还可以使用null合并运算符,如果任何一个列表为null,则返回一个空列表(内部it也会检查null)
您可以这样做:
(mIds ?? Enumerable.Empty<int>()).Union(yourIds ?? Enumerable.Empty<int>())

(感谢@phoog 评论

但在我看来,最好检查是否为null

但如果列表中有任何一个为空,则无需进行任何检查,不会出现异常。即使两个列表都为空,您也将获得一个空结果返回。上面的代码如果列表中有任何一个是null,它将返回一个空列表。


4
您可以使用 myIds = myIds ?? Enumerable.Empty<int>(); 来避免不必要地实例化新的列表。但是,替换表达式中的空对象并不能避免 lambda 表达式中的空引用异常。 - phoog
这个是可以工作的,但就像你提到的那样,检查列表是否为null可能同样有效。 - navig8tr
@phoog,您提出的点子很好。我不记得以前见过 Enumerable.Empty - Habib
由于只有在两个值都不为空时才需要使用Union(),因此可能更高效(但不太优雅)的解决方案是执行myids != null && yourids != null ? myids.Union(yourids) : (myids ?? yourids ?? Enumerable.Empty<int>())。特别是当您经常需要在Union()之后执行其他操作,例如Distinct()。 - bdrajer

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