代码之家  ›  专栏  ›  技术社区  ›  Ibanez1408

列表中的方法“Except”在C中没有给出正确的信息#

  •  0
  • Ibanez1408  · 技术社区  · 7 年前

    我有两张清单 ManualReadTag 物体: _manualReadTagList mrt .中的条目 捷运 _手册标签列表 .我需要从 _手册标签列表 这是“不”存在于 捷运 .我就是这样做的:

    IEnumerable<ManualReadTag> difference = _manualReadTagList.Except(mrt).ToList();
    

    但这是行不通的。我得到了manualReadTagList中的所有记录,而不仅仅是捷运中没有的记录。以下是我如何填写捷运

    var mrt = (from ManualReadTag row in ViewingGridFromComparison.ItemsSource
                    select new ManualReadTag
                    {
                        Plaza = Convert.ToInt16(row.Plaza),
                        Lane = Convert.ToInt16(row.Lane),
                        Trxn_DTime = Convert.ToDateTime(row.Trxn_DTime),
                        Tag_Number = row.Tag_Number
                    }).ToList();
    
    IEnumerable<ManualReadTag> difference = _manualReadTagList.Except(mrt).ToList();
    ViewingGrid.ItemsSource = difference;
    

    你能告诉我怎么做吗。非常感谢。

    0 回复  |  直到 7 年前
        1
  •  1
  •   Caius Jard    7 年前

    问题是,如果你没有覆盖Equals等,那么在创建 mrt 通过从旧对象中复制数据项创建了新对象。这意味着基于ManualReadTag对象的内存地址的Equals和GetHashCode的默认规定是不同的,并且这些对象被认为是不相等的:

    ManualReadTag a = new ManualReadTag(){ SomeProperty = 123 };
    ManualReadTag b = new ManualReadTag(){ SomeProperty = a.SomeProperty };
    ManualReadTag c = a;
    
    a.Equals(b) //false even though they have identical property values, memory addresses are different
    a.Equals(c); //true
    

    您需要重用相同的对象,以便基于内存地址的相等断言为真:

    //only works if ItemsSource was made from _manualReadTagList
    _manualReadTagList.Except( ViewingGridFromComparison.ItemsSource)
    

    或者你需要覆盖ManualReadTag上的Equals和GetHashCode(为了获得最佳性能,我们将从mrt构建一个哈希集,然后迭代_mnualReadTagList,对其中的所有内容进行哈希运算,并在从mrt创建的哈希集中查找它。因此,它需要能够计算ManualReadTag的哈希,然后,因为理论上可能有两个不同的对象具有相同的哈希代码,所以使用Equals绝对验证它们是否是sam。)e或者hashcode是否应该相等)

    或者,您需要创建自己的IEqualityComparer类(有关示例,请参阅文档: https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except -此代码示例还可以用作覆盖ManualReadTag上的Equals和GetHashCode的基础)

    或者你需要放弃,除了自己滚;将MRT转换成一个哈希集或字典(有快速查找的东西),基于您所考虑的属性使两个MalueRead TAG实例相同,并且除了通过迭代MyAualRead TrastRead进行检查之外,检查在MRT - Michal中的每一个元素都做了类似的事情,尽管LINQ解决方案可能使用嵌套循环,如果MRT列表大,则性能可能较差。

        2
  •  0
  •   Michał Turczyn    7 年前

    你知道如何比较两门课,你提到:

    你理解错了_manualReadTagList有1,2,3,4,5,6,mrt有2,4,所以我应该得到1,3,5,6

    这些数字来自哪里???我猜是场地 Tag_Number 在里面 ManualReadTag 类(如果不同,只需替换下面代码中的字段即可)。因此,您需要以下代码:

    _manualReadTagList
      .Where(m => !mrt.Select(i => i.Tag_Number).Contains(m.Tag_Number))
      .ToList();
    

    另一种方法是覆盖 Equals 方法 ManualReadTag 根据特定字段检查实例的相等性(我假设 标签号 ).