从列表中删除特定条目(c#初学者)

本文关键字:初学者 列表 删除 | 更新日期: 2023-09-27 18:20:17

我有一个简单的静态库存类,它是自定义类Item的列表。我正在制作一个制作系统,当我制作一些东西时,我需要从我的库存清单中删除所需的物品。

我试图创建一个可以调用的方法,该方法将要删除的项的数组作为参数,但不起作用。

我认为这是因为foreach循环不知道要删除哪些项目?我没有收到错误消息,只是不起作用。我怎样才能做到这一点?

public class PlayerInventory: MonoBehaviour 
{
    public Texture2D tempIcon;
    private static List<Item> _inventory=new List<Item>();
    public static List<Item> Inventory 
    {
        get { return _inventory; }
    }
    public static void RemoveCraftedMaterialsFromInventory(Item[] items) 
    {
        foreach(Item item in items) 
        {
            PlayerInventory._inventory.Remove(item);
        }
    }
}

以下是显示将删除哪些项目的功能:

    public static Item[] BowAndArrowReqs()
{
    Item requiredItem1 = ObjectGenerator.CreateItem(CraftingMatType.BasicWood);
    Item requiredItem2 = ObjectGenerator.CreateItem(CraftingMatType.BasicWood);
    Item requiredItem3 = ObjectGenerator.CreateItem(CraftingMatType.String);
    Item[] arrowRequiredItems = new Item[]{requiredItem1, requiredItem2, requiredItem3};
    return arrowRequiredItems;
}

这就是所谓的

THis在RecipeCheck静态类中:

PlayerInventory.RemoveCraftedMaterialsFromInventory(RecipeCheck.BowAndArrowReqs());

从列表中删除特定条目(c#初学者)

虽然我喜欢Jame的回答(它充分涵盖了合同),但我将讨论如何实现这种平等,并提出一些意见。

对于starts,在返回的列表中可能存在多个相同类型的对象,例如BasicWood、String。然后需要为每个新对象使用一个鉴别器

如果RemoveCraftedMaterialsFromInventory(new [] { aWoodBlock })以两块木板相互检查("相等")的方式移除一块木板,那将是糟糕的。这是因为"与工艺兼容"并不一定等同于"平等"。

一种简单的方法是为每个特定对象分配一个唯一的ID(请参阅Guid.NewGuid)。该字段将在Equals方法中使用(并且可以独占使用)-然而,现在我们回到最初的问题,其中每个新对象都不同于任何其他

那么,解决方案是什么呢?移除时,请确保使用等效(或相同的对象)!

List<Item> items = new List<Item> {
    new Wood { Condition = Wood.Rotten },
    new Wood { Condition = Wood.Epic },
};
// We find the EXISTING objects that we already have ..
var woodToBurn = items.OfType<Wood>
    .Where(w => w.Condition == Wood.Rotten);
// .. so we can remove them
foreach (var wood in woodToBurn) {
   items.Remove(wood);
}

好吧,好吧,这是不可能的,但我们会说:"我们怎么能用一个配方来做到这一点,这样Equals就不会被屠杀,但它会删除任何给定类型的物品?"

好吧,我们可以通过使用LINQ或支持谓词的List方法(即List.FindIndex)来实现这一点,或者我们可以实现一个仅在这种情况下使用的特殊Equatable。

使用谓词的实现可能看起来像:

foreach (var recipeItem in recipeItems) {
    // List sort of sucks; this implementation also has bad bounds
    var index = items.FindIndex((item) => {
       return recipeItem.MaterialType == item.MaterialType;
    });
    if (index >= 0) {
       items.RemoveAt(index);
    } else {
       // Missing material :(
    }
}

如果类Item没有实现IEquatable<Item>bool Equals(Item other)方法,那么默认情况下它将使用Object.Equals来检查它们是否是同一对象。(不是两个具有相同值的对象——相同的对象)。

由于您没有说明Item是如何实现的,因此我不能建议如何编写它的Equals(),但是,您也应该重写GetHashCode(),以便两个Equal项返回相同的哈希代码。

更新(基于评论):本质上,List.Remote的工作原理是这样的:

  foreach(var t in theList)
  {
         if (t.Equals(itemToBeRemove))
              PerformSomeMagicToRemove(t);
  }

所以,你不必对你在问题中给出的代码做任何事情。只需将Equals()方法添加到Item中即可。