【问题标题】:Why changing one item in a linq group affects other items in the same group?为什么更改 linq 组中的一项会影响同一组中的其他项?
【发布时间】:2013-05-19 21:09:48
【问题描述】:

我正在编写一些类似这样的 C# 代码:

public class Item
{
   public bool flag { get; set; }
   public string itemName { get; private set;};

   Item(string _name)
   {
       this.itemName = _name;
       this.flag     = false;
   }
}

public class MainClass
{
    public static void Main() 
    {
        List itemList = new List<Item>();
        itemList.Add(new Item("ProductA");
        itemList.Add(new Item("ProductA");
        itemList.Add(new Item("ProductB");

        var itemGroups = from item in itemList group item by item.itemName;
        foreach (var itemGroup in itemGroups)
        {
            foreach (Item i in itemGroup)
            {
                i.flag = true;
                break;
            }
        }
    }
 }

我想在这里实现的是只更改组中的一个项目,而不触及同一组中的其他项目。从上面的代码中,我期望只有 itemName 为“ProductA”的第一个项目的标志设置为 true。但结果是这两个项目(项目名称为“ProductA”)的标志都设置为 true。

我是 linq 的新手。我做错了什么吗?或者我怎样才能在这里实现目标?

非常感谢!!!

道格

【问题讨论】:

  • 您有 2 个同名项目。 ProductA
  • But the result is that Both the items (with itemName "ProductA") have its flag being set to true 再次调试您的代码。它可以按您的预期工作。
  • 确定这是您的实际代码吗?您确定您没有两次添加相同的商品引用,因此实际上您只有 1 个产品 A,但同一个产品被列出了两次?意思是,你能在上面的代码中重现这个问题,还是那个代码被简化了?

标签: c# linq


【解决方案1】:

我无法重现您的场景,因为它的每个项目都是唯一的 Item 类型。可能在您的代码中,您可能不小心将一个项目两次添加到您的列表中,例如

Item item1 = new Item("ProductA");
listItem.Add(item1);
....
listItem.Add(item1);

在这种情况下,在以后的任何时间点,如果您将 itemname 更新为“ProductA”的项目,那么该更改将反映在列表的两个元素中。请检查这个案例。

【讨论】:

  • 谢谢大家!这是我的坏事。我确实添加了两次相同的实例。该示例应按预期工作。
  • 那么我建议你接受这个问题的答案,很高兴你解决了:) 另外,考虑下载LINQPad 并在发布之前尝试你的代码,它会让你们更容易和其他人来帮助你。
【解决方案2】:

我想在这里实现的是只更改组中的一项 不接触同一组中的其他项目。从上面的代码,我 期望只有 itemName "ProductA" 的第一个项目有它的标志 设置为真。

你的代码没问题,在调试器中检查:

//ProductA
itemGroups.ToList()[0].ToList()[0].flag //true
itemGroups.ToList()[0].ToList()[1].flag //false

//ProductB
itemGroups.ToList()[1].ToList()[0].flag //true

【讨论】:

    【解决方案3】:

    您的代码枚举了组中的所有项目。

            foreach (Item i in itemGroup)
            {
                i.flag = true;
                break;
            }
    

    你需要得到第一个。使用 First 或 FirstOrDefault 方法

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-30
      相关资源
      最近更新 更多