2

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

我有一堂课:

class Item
{
   int ID;
   bool Selected;
}

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

List<Item> ListA = GetListA();
List<Item> ListB = GetListB();

现在我想创建第三个列表,其中包含来自ListB. 重要的是,如果在中ID找到匹配项(相同),ListA那么我想使用该Selected值,否则我想保留在Selected中的项目的值ListB

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

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

重要提示:我不想显得无知,但我不想改变ListC创建方式。我的意思是我想使用“linq select”方法,并且我想使用一个分配Selected值的“one liner”......我知道还有其他方法可以创建可以正常工作的列表,但是我不会学到任何新东西。


到目前为止,我已经尝试了几件事......

我知道这会起作用,但我不想查询ListA两次:

Selected = ListA.Any(x => x.ID == item.ID) ? ListA.First(x => x.ID == item.ID).Selected : item.Selected

我也尝试过使用DeafultIfEmpty,但我认为这不是这种情况的正确想法......因为它不起作用,而且如果它是ListA空的,它似乎更有用(我不在乎)

4

2 回答 2

7

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

Selected = (ListA.FirstOrDefault(x => x.ID == item.ID) ?? item).Selected;

因为DefaultIfEmpty,你必须做

Selected = ListA.Where(x => x.ID == item.ID).DefaultIfEmpty(item)
                                                       .First().Selected;

这更难遵循,但基本上做同样的事情。

正如 Dominic 在下面所指出的,如果您使用SingleOrDefault/Single代替,如果您在其中找到两个相同的FirstOrDefault/First项目,您将得到一个例外- 这可能是您想要引入的支票。ListAID

(有更好/更有效的方法可以做到这一点,但正如你所说,你想修复这种方式,而不是使用完全不同的方式。)

于 2012-11-29T10:56:26.087 回答
2

那这个呢?

var query = from b in ListB
        join a in ListA
            on b.ID equals a.ID into g
        from r in g.DefaultIfEmpty(b)
        select new Item { ID = b.ID, Selected = r.Selected };
于 2012-11-29T11:17:48.590 回答