从列表中删除特定条目(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());
虽然我喜欢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中即可。