List.Contains在通过foreach循环进行交互时不起作用

时间:2016-09-26 11:35:55

标签: c# list foreach contains

我有一个FilterItems列表(称为过滤器)。每个FilterItem都包含一个字符串&布尔值。例如“0”和假。

我已经宣布了这样的名单:

 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循环再次迭代时。

4 个答案:

答案 0 :(得分:2)

'问题是,即使myItem与列表中已有的项目相同,Contained的结果也始终为false 事实上它不是 - 你总是实例化新对象,而.Contains方法只比较引用。 这里最好的方法是检查列表中是否已经有一组具有相同属性的项目:

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

应该这样做,因为你不是比较参考而是比较项目的实际属性。

答案 1 :(得分:0)

根据this线程,.Contains()对类使用默认的IEqualityComparer,因此,在大多数情况下,它会将引用与对象进行比较。

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

答案 2 :(得分:0)

代码<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="intro"> <h1>Hello, my name is I am a</h1> <h2 class="quotes">quote 1</h2> <h2 class="quotes">quote 2</h2> <h2 class="quotes">quote 3</h2> <h1>currently based in London, GBR</h1> </div>完全相同,它会创建一个新的过滤器项。该新项目与任何其他对象不同,即使属性完全相同,也是一个不同的实例。

如果您将第一个if语句更改为:

new FilerItem

您将实际比较属性。或者,您可以覆盖if(!filter.Any(i => i.Name == myItem.Name && i.Checked == myItem.Checked)) { //... 类中的Equals方法或实现FilterItem

答案 3 :(得分:0)

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