0

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

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

我认为这是因为 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;
}

这就是所谓的:

这是在 RecipeCheck 静态类中:

PlayerInventory.RemoveCraftedMaterialsFromInventory(RecipeCheck.BowAndArrowReqs());
4

2 回答 2

0

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

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

更新(基于评论):本质上, List.Remove 像这样工作:

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

因此,您不必对您在问题中给出的代码做任何事情。只需将 Equals() 方法添加到 Item。

于 2013-06-28T01:48:19.770 回答
0

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

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

RemoveCraftedMaterialsFromInventory(new [] { aWoodBlock })如果以与两个木块相互检查(“相等”)相同的方式移除一块木块,那将是不好的。这是因为“适合制作”不一定与“平等”相同。

Guid.NewGuid一种简单的方法是为每个特定对象分配一个唯一 ID(请参阅 参考资料)。该字段将在 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.FindIndex)的 List 方法来做到这一点,或者我们可以实现一个特殊的 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 :(
    }
}
于 2013-06-28T01:58:31.243 回答