【问题标题】:System.InvalidOperationException in my c# project我的 c# 项目中的 System.InvalidOperationException
【发布时间】:2018-06-10 16:47:58
【问题描述】:

我的项目是关于一个类 Account 和 2 个子类(活期账户和存款账户)。

我主要创建了一个帐户数组列表 但我试图在这个方法中删除一个对象:

    public static void Remove(ArrayList L, int accnb)
    {
        foreach(Account obj in L)
        {
            if(obj.AccN == accnb)
                L.Remove(obj);
        }
    }

但我收到一个错误:集合已修改;枚举操作可能无法执行。

所有其他方法,如添加或返回字符串都可以正常工作..

【问题讨论】:

    标签: c# oop


    【解决方案1】:

    ArrayList 中的项目键入为object。因此,C# 不知道他们有一个名为AccN 的成员。

    有一个强类型的通用等价物ArrayList,名为List<T>。在这里,您在创建列表时明确指定列表项的类型

    List<Account> accounts = new List<Account>();
    

    此列表还可以包含派生类CurrentAccountDepositAccount 的对象。像这样使用它

    public static void Remove(List<Account> L, int accnb)
    {
        foreach(Account acc in L)
        {
            if(acc.AccN == accnb)
                L.Remove(acc);
        }
    }
    

    注意:在 C# 1.0 和 C# 1.1 中没有泛型。因此,实现了弱类型集合ArrayList。由于泛型是在 C# 2.0 中引入的,因此这种类型大多已过时。

    使用ArrayList,您必须将对象转换为正确的类型才能使其工作

    if(((Account)acc).AccN == accnb)
    

    您还有另一个问题。您不能更改使用foreach 枚举的集合,因为这会混淆foreach。请改用 for 循环,并确保以相反的顺序循环,以免在删除项目时更改前面项目的索引。

    for (int i = L.Count - 1; i >= 0; i--) {
        if (L[i].AccN == accnb) {
            L.RemoveAt(i);
        }
    }
    

    C# Reference 说:

    foreach 语句用于遍历集合以获取您想要的信息,但不能用于从源集合中添加或删除项目以避免不可预知的副作用。如果您需要从源集合中添加或删除项目,请使用 for 循环。

    【讨论】:

    • aah okk cause List doesn't work, I got an error The type or namespace name 'List' could not be found(您是否缺少 using 指令或程序集引用?
    • 在代码顶部添加using System.Collections.Generic 或使用为您完成此操作的灯泡。
    • 它不起作用:/我尝试了上面的答案,它有效,但对我来说是新的
    • 问题很可能是您正在修改foreach 中的集合。请参阅我的更新答案。
    【解决方案2】:

    foreach 实际上并不适用于集合,而是适用于Enumerators。虽然所有集合都可以隐式转换为 Enumerator,但 Enumeartor 规则仍然适用。

    所以基本上你的代码被解释为:

    temp IEnumerator = L.GetEnumerator();
    foreach(Account obj in temp)

    所有枚举器都有一个规则,即您不能更改基础集合。这样做将(必须)使枚举数无效。除了 .Current() 的下一次调用之外,Wich 会抛出所说的。

    由于您在使用枚举器时无法更改集合,而 foreach 仅在底层使用枚举器,这意味着您在使用 foreach 时无法更改 colelciton(包括删除元素)。您需要一个更冗长的循环来执行此操作。

    【讨论】:

      【解决方案3】:

      在使用 foreach 迭代集合时不要删除元素。

      另外,我建议使用List&lt;T&gt; 而不是ArrayList

      解决手头任务的更简单方法是:

      public static void Remove(List<Account> L, int accnb) => 
                                  L.RemoveAll(obj => obj.AccN == accnb);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-03-02
        • 1970-01-01
        • 2018-02-13
        • 2013-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-26
        相关资源
        最近更新 更多