在 LINQ 内部联接中保留空值

问题描述

代码specialthings 进行内部连接,然后将索引生成到相应匹配项的 things 中:

object[] special = {      'b',null,5.0f,"notme" };
object[] things  = { "a",'b',3,6.0          };

var specialThingIndices = from tn in things.Select((t,n) => (t,n)) 
                          join s in special on tn.t equals s
                          select tn.n;

foreach (var n in specialThingIndices)
    Console.WriteLine($"[{n}] = {Convert.ToString(things[n])},{things[n] is null}");

输出

[1] = b,False
[4] = 5,False

然而,null 出现在两个数组中,我不想跳过它。所以我希望输出的是:

[1] = b,False
[3] =,True
[4] = 5,False

为什么它看不到 null 以及如何让它保留它们?

我尝试在不同的地方手动应用 DefaultIfEmpty() 但没有成功。我也尝试用 equals 替换 == 但我想这不是有效的语法。我想不出别的了。

可运行示例为 here

解决方法

如果为空,您可以选择默认值,例如 "<null>" 字符串。

...
object[] special = { 'b',null,5.0f,"notme" };
object[] things = { "a",'b',3,6.0 };

var specialThingIndices = from tn in things.Select(x => x ?? "<null>").Select((t,n) => (t,n))
                          join s in special.Select(x => x ?? "<null>") on tn.t equals s
                          select tn.n;

foreach (var n in specialThingIndices)
    Debug.WriteLine($"[{n}] = {Convert.ToString(things[n])},{things[n] is null}");
...

编辑 使用 Where 而不是 join 的另一种解决方案。

...
object[] special = { 'b',6.0 };

var specialThingIndices = from tn in things.Select((t,n))
                          where special.Any(s => Equals(s,tn.t))
                          select tn.n;

foreach (var n in specialThingIndices)
    Debug.WriteLine($"[{n}] = {Convert.ToString(things[n])},{things[n] is null}");
...