【问题标题】:Removing items from ObservableCollection [duplicate]从 ObservableCollection 中删除项目 [重复]
【发布时间】:2021-04-21 12:23:17
【问题描述】:

我遇到了ObservableCollection 的问题。我有两个ObservableCollection。一个是旧的,另一个是新的。我想检查旧项目中是否有新项目中没有的项目并将其删除(从旧项目中)。

public class Class1
{
    private ObservableCollection<String> m_Files = new ObservableCollection<String>();

    public void update()
    {
        ObservableCollection<String> tmp_Files = new ObservableCollection<String>();
        tmp_Files.Add("Foo");
        tmp_Files.Add("Bar");
    
        this.m_Files.Add("Boing");
        this.m_Files.Add("Foo");
        this.m_Files.Add("Bar"); 

        this.m_Files = RemoveObsoleteFiles(this.m_Files, tmp_Files);
    }


    private ObservableCollection<String> RemoveObsoleteFiles(ObservableCollection<String> files_OLD, ObservableCollection<String> files_NEW)
    {
        ObservableCollection<String> result = files_OLD;
        foreach (String item in files_OLD)
        {
            if (!files_NEW.Contains(item))
            {
                result.Remove(item);
            }
        }
        return result;
    }
}

当调用RemoveObsoleteFiles() 方法时出现错误:

System.InvalidOperationException: '集合已修改;枚举操作可能无法执行。'

单步执行代码我注意到result 更改时tmp_Files 也会更改。

这是为什么呢?如何避免?

【问题讨论】:

  • 你打错字了,应该是files_NEW.Remove(item)

标签: c# observablecollection


【解决方案1】:

单步执行代码时,我注意到result 更改时tmp_Files 也会更改。

那是因为它们引用了同一个集合。如果您不想想要 tmp_Files 更改,那么您需要复制它:

ObservableCollection<String> result = new Observablecollection<String>(files_OLD)

但是,我怀疑这不是问题,因为无论如何您都不会对 tmp_files 做任何事情,但最好不要修改传入的集合并返回修改后的副本。

至于例外,当您使用foreach 迭代集合时,您无法从集合中删除项目。循环时删除项目的最简单方法是使用for 循环并迭代向后(做一些研究找出原因):

for(int i=files_OLD.Count - 1; i>=0; i--)
{
    String item = files_OLD[i];
    if (!files_NEW.Contains(item))
    {
        result.Remove(item);
    }
}

【讨论】:

  • 如果你打算为了优化而进行反向迭代,你也可以使用RemoveAt(i)。 :-)
  • @StriplingWarrior 这不是为了优化 - 如果您向前迭代并删除一个项目,则随着迭代器向前移动,下一个项目将被跳过。但是,是的,RemoveAt(i) 也可以工作(但您仍然无法在删除时不调整索引的情况下向前迭代)。
  • 好吧,如果您不进行优化,只需调用ToList() 似乎就足够了,这样您就可以遍历不同的实例。 files_OLD.Where(f =&gt; !files_NEW.Contains(f)).ToList().ForEach(i =&gt; files_OLD.Remove(i));
猜你喜欢
  • 1970-01-01
  • 2012-07-30
  • 2017-08-09
  • 2019-05-01
  • 1970-01-01
  • 2014-07-07
  • 1970-01-01
  • 2021-01-25
  • 1970-01-01
相关资源
最近更新 更多