Linq选择:使用列表中的值(如果可用)

mus*_*fan 2 c# linq

我将使用一些基本的精简示例来说明我的问题.

我有一节课:

class Item
{
   int ID;
   bool Selected;
}
Run Code Online (Sandbox Code Playgroud)

现在假设我有两个Item类列表:

List<Item> ListA = GetListA();
List<Item> ListB = GetListB();
Run Code Online (Sandbox Code Playgroud)

现在我想创建一个包含所有项目的第三个列表ListB.重要的是,如果匹配(相同ID)如果找到ListA然后我想使用该Selected值,否则我想保留项目的SelectedListB.

我正在创建第三个列表如下:

List<Item> ListC = from item in ListB 
select new Item
{
   ID = item.ID,
   Selected = item.Selected// <-- should use value form ListA if available
};
Run Code Online (Sandbox Code Playgroud)

重要提示:我不想显得无知,但我并不想改变的方式ListC创建.我的意思是我想使用"linq选择"方法,我想使用一个"一个班轮"来分配Selected值...我知道有其他方法来创建列表,它将工作得很好,但随后我不会学到任何新东西.


到目前为止,我尝试过几件事......

我知道这会有效,但我不想查询ListA两次:

Selected = ListA.Any(x => x.ID == item.ID) ? ListA.First(x => x.ID == item.ID).Selected : item.Selected
Run Code Online (Sandbox Code Playgroud)

我也尝试过使用,DeafultIfEmpty但我不认为这是正确的思考这种情况...因为它不起作用,如果ListA是空的话似乎更有用(我不关心)

Raw*_*ing 7

您可以按如下方式修改最后一行代码:

Selected = (ListA.FirstOrDefault(x => x.ID == item.ID) ?? item).Selected;
Run Code Online (Sandbox Code Playgroud)

因为DefaultIfEmpty,你必须这样做

Selected = ListA.Where(x => x.ID == item.ID).DefaultIfEmpty(item)
                                                       .First().Selected;
Run Code Online (Sandbox Code Playgroud)

这更难以遵循,但基本上是相同的事情.

正如Dominic在下面提到的那样,如果你用SingleOrDefault/Single它代替FirstOrDefault/First,你会得到一个例外,如果你发现两个ListA相同的项目ID- 这可能是你想要介绍的检查.

(目前这样做的更好/更有效的方式,但正如你所说,你要修复做的方式,而不是用一种完全不同的方式.)