列表.包含在遍历foreach循环时不起作用

本文关键字:循环 不起作用 foreach 遍历 包含 列表 | 更新日期: 2023-09-27 18:09:02

我有一个FilterItems列表(称为filter)。每个FilterItem由一个字符串&布尔值。如。"0"和false

我已经像这样声明了这个列表:

 List<FilterItem> filter = new List<FilterItem>();

然后遍历一个数据表列,目的是将该列中的每个值添加到过滤器中——如果一个值出现两次——不要向过滤器列表添加重复条目。这就是我正在做的:

List<FilterItem> filter = new List<FilterItem>(); //initialise new list
foreach (DataRow row in RawResults.Rows) //For each row in DT
{
    FilterItem myItem = new FilterItem { Name = row.ItemArray[i].ToString(), Checked = CheckState.Checked }; //create item
    if (!filter.Contains(myItem)) //if item doesn't exist
    {
        filter.Add(myItem); //add it
    }
}

问题是,即使myItem与列表中已经存在的项目相同,Contains的结果也总是false -我认为这是因为foreach循环-但我不明白为什么,因为过滤器列表在该循环之外声明。我也试过在foreach循环之外声明myItem,这没有任何区别。

如果我做以下操作:

List<FilterItem> filter = new List<FilterItem>(); //initialise new list
foreach (DataRow row in RawResults.Rows) //For each row in DT
{
    FilterItem myItem = new FilterItem { Name = row.ItemArray[i].ToString(), Checked = CheckState.Checked }; //create item
    if (!filter.Contains(myItem)) //if item doesn't exist
    {
        filter.Add(myItem); //add it
    }
    FilterItem myItem = new FilterItem { Name = row.ItemArray[i].ToString(), Checked = CheckState.Checked }; //create item
    if (!filter.Contains(myItem)) //if item doesn't exist
    {
        filter.Add(myItem); //add it
    }
}

第二次调用. contains(在foreach循环的同一迭代中),它正确地变为true,只是在foreach循环再次迭代时不是。

列表.包含在遍历foreach循环时不起作用

'问题是,包含的结果总是假的,即使myItem是相同的项目已经在列表中'事实上它不是——你总是实例化新对象,. contains方法只比较引用。这里最好的方法是检查列表中是否已经有具有相同属性集的项:

!filter.Any(item => item.Name == myItem.Namae && item.Checked == myItem.Checked);

应该能达到这个目的,因为你不是在比较引用,而是在比较项目的实际属性。

根据这个线程,. contains()使用默认的IEqualityComparer作为类,因此,在大多数情况下,它比较引用和对象。

为了检查元素是否确实包含,您需要使用.Any()或实现自己的相等比较器。

代码new FilerItem正是这样做的,它创建了一个新的过滤器项。这个新项目不同于任何其他对象,即使属性完全相同,它也是一个不同的实例。

如果你把第一个If语句改成:

if(!filter.Any(i => i.Name == myItem.Name && i.Checked == myItem.Checked)) { //...

您将实际比较属性。或者,您可以在FilterItem类中重写Equals方法或实现IEquatable<T>

你应该考虑在FilterItem类中重写Equals和GetHashCode方法。这样,根据用于存储FilterItem实例的集合,相应的方法将在调用特定集合上的Add/Contains方法时被触发。