无法使用委托<Action>方法从IList<T>中移除对象| C#控制台应用程序

huangapple go评论60阅读模式
英文:

Unable to remove an object from an IList<T> using delegate <Action> method| C# Console Application

问题

以下是您提供的内容的翻译:

这是我的列表:

public IList<Food> Foods { get; } = new List<Food>();

接受IList<T>Action<IList<T>>作为其参数的通用方法:

public void Process<T>(IList<T> items, Action<IList<T>> disposal)
{
     disposal(items);
}

我在Main方法中的做法:

using Generics03.Models;
using Generics03.Systems;

Multislut ms = new Multislut() { };
ms.Foods.Add(new Food());
ms.Foods.Add(new Food());
ms.Foods.Add(new Food());

ms.Process<Food>(ms.Foods, (f) => {
    f[0].Name = "Pizza";
    f[0].Region = "Italy";
    
    //添加以下方法后,项目无法运行!
    f.GrowKale();
}

//Composter.cs,其中定义了GrowKale方法
public static class Composter
{
     public static void GrowKale(this IList<Food> foods)
     {
           foreach (var item in foods)
           {
                foods.Remove(item);
           }           
      }    
}

我只需要移除Program.cs/Main()中添加的ms.Foods对象,我可以为其属性赋值,但无法移除或添加对象到ms.Foods列表,会得到以下异常消息:

Unhandled exception. System.InvalidOperationException: Collection was modified; enumeration operation may not execute.

是否有方法可以做到这一点?

英文:

Here is my list:
public IList&lt;Food&gt; Foods { get; } = new List&lt;Food&gt;();

The generic method which recives IList<T> and an Action<T> as it's argument:

public void Process&lt;T&gt;(IList&lt;T&gt; items, Action&lt;IList&lt;T&gt;&gt; disposal)
{
     disposal(items);
}

The way I did inside Main method:

using Generics03.Models;
using Generics03.Systems;

Multislut ms=new Multislut(){};
ms.Foods.Add(new Food());
ms.Foods.Add(new Food());
ms.Foods.Add(new Food());

ms.Process&lt;Food&gt;(ms.Foods,(f)=&gt;{
    f[0].Name=&quot;Pizza&quot;;
    f[0].Region=&quot;Italy&quot;;
    
    //when adding the following method, the project doesn&#39;t run!
    f.GrowKale();

    //Composter.cs where the Growkale method is defined in
public static class Composter
{
     public static void GrowKale(this IList&lt;Food&gt; foods)
     {
           foreach (var item in foods)
           {
                foods.Remove(item);
           }           
      }    
}

All I need to do is to remove ms.Foods objects that I've added in Program.cs/Main(), I'm able to assign value to their properties but not able to remove or even add object to the ms.Foods list, getting the following exception message:

Unhandled exception. System.InvalidOperationException: Collection was modified; enumeration operation may not execute.

Is there a way to do so?

答案1

得分: 2

应该在尝试移除项目之前创建 List 的副本,

你不能在枚举时从正在枚举的 List 中移除项目,否则会抛出你所看到的异常,这是为了防止你创建新旧值混杂的情况,强制你重新开始。

最简单的方法是使用 .ToList()

foreach (var item in foods.ToList())
{
    foods.Remove(item);
}

为了使其更易阅读/理解,你还可以这样做

var theComposter = foods.ToList();
foreach (var food in theComposter)
{
    foods.Remove(food);
}

你还应该考虑在尝试获取/设置 foods 时使用 lock,以防止在多线程情况下再次看到这个错误。

英文:

You should create a copy of the List before you try remove items,

You can't remove items from the List you are Enumerating without throwing the exception you are seeing, This is to stop you from creating situations where you end up with new and old values and forces you to start again.

The easiest way to do this is with .ToList()

       foreach (var item in foods.ToList())
       {
            foods.Remove(item);
       }  

to make it easier to read/understand you could also do this

       var theComposter = foods.ToList();
       foreach (var food in theComposter)
       {
            foods.Remove(food);
       }  

You should also consider using a lock whenever you try to get/set the foods so you don't see this error again if you use multiple threads.

huangapple
  • 本文由 发表于 2023年2月10日 16:28:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/75408580.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定