C# C更改列表中的对象
我在使用已找到的索引更改列表中对象的成员时遇到了一个小问题 这就是我目前正在使用的方法:C# C更改列表中的对象,c#,list,C#,List,我在使用已找到的索引更改列表中对象的成员时遇到了一个小问题 这就是我目前正在使用的方法: static void addToInventory(ref List<baseItem> myArray, baseItem item, float maxAmount, ref float currentAmount) { if (currentAmount + item.getWeight() <= maxAmount) { Console.Write
static void addToInventory(ref List<baseItem> myArray, baseItem item, float maxAmount, ref float currentAmount)
{
if (currentAmount + item.getWeight() <= maxAmount)
{
Console.WriteLine("item.Quantity = {0}", item.Quantity);
if (myArray.Contains(item))
{
Console.WriteLine("Item ({0}) already exists", item.Name);
int id = myArray.IndexOf(item);
myArray[id].Quantity += item.Quantity;//Change occurs in this line, item.Quantity becomes the same as myArray[id].Quantity
}
else
{
Console.WriteLine("Adding new item ({0})", item.Name);
myArray.Add(item);
}
currentAmount += item.getWeight();
}
else
{
Console.WriteLine("Inventory full");
}
myArray.Sort();
}
此方法采用多个参数,包括库存/列表。我检查该项目是否适合,如果适合,我会查看列表中是否有另一个同名项目,找到索引,然后添加更多项目。但是,添加的项目数量突然与列表中项目的数量相同。出于某种原因,这也会更改列表外项目的数量。因此,不是数量加起来像这样:1,2,3,4,它们加起来像这样:1,2,4,8。如何使添加的项目的数量不发生变化
我刚刚开始学习如何使用列表,所以如果我遗漏了什么,请毫不犹豫地批评。提前谢谢
标记:
谢谢你的快速回复!
很抱歉,命名myArray很糟糕;它曾经是一个ArrayList。currentAmount和maxAmount分别指库存中的当前重量和库存可容纳的最大重量。另外,我不想只在数量上加1;我希望它添加我传入的项目的数量。谢谢你的提示。我可能会考虑改用Dictionary。这里发生的事情是myArray[id]和item引用同一个对象。包含按引用而不是按值进行的比较 所以看起来你只想这么做
if (myArray.Contains(item))
{
item.Quantity++;
}
指示列表中还有一个项目
然而,以这种方式使用列表是一种根本不正确的方法。您应该使用字典或集合来实现O1查找
如果您选择字典路径,您将得到如下结果:
// a Set might be better -- I don't know what you're using this for
var myDict = new Dictionary<string, BaseItem>();
// ...
if (currentAmount + item.Weight <= maxAmount)
{
if (myDict.ContainsKey(item.Name))
{
Console.WriteLine("Item already exists");
item.Quantity++;
}
else
{
Console.WriteLine("Adding new item");
myDict[item.Name] = item;
}
currentAmount += item.Weight;
}
else
{
Console.WriteLine("Full");
}
其他一些注意事项:
除非你知道自己在做什么,否则要避免。没有理由让名字不好的myArray myList成为一种改进,但清单将作为参考在这里传递。
优先于getXXX方法。
与任意静态方法相比,更喜欢类。您在这里描述的方法听起来像是属于Inventory类,而不是与某个特定实例无关的静态方法。ref float currentAmount应该是类的成员,而不是方法的显式参数。
检查一下你的代码。这将迫使您养成良好的C风格习惯,例如用大写字母命名类和方法,以及在get/set方法上使用属性。
这里发生的是myArray[id]和item引用同一个对象。包含按引用而不是按值进行的比较 所以看起来你只想这么做
if (myArray.Contains(item))
{
item.Quantity++;
}
指示列表中还有一个项目
然而,以这种方式使用列表是一种根本不正确的方法。您应该使用字典或集合来实现O1查找
如果您选择字典路径,您将得到如下结果:
// a Set might be better -- I don't know what you're using this for
var myDict = new Dictionary<string, BaseItem>();
// ...
if (currentAmount + item.Weight <= maxAmount)
{
if (myDict.ContainsKey(item.Name))
{
Console.WriteLine("Item already exists");
item.Quantity++;
}
else
{
Console.WriteLine("Adding new item");
myDict[item.Name] = item;
}
currentAmount += item.Weight;
}
else
{
Console.WriteLine("Full");
}
其他一些注意事项:
除非你知道自己在做什么,否则要避免。没有理由让名字不好的myArray myList成为一种改进,但清单将作为参考在这里传递。
优先于getXXX方法。
与任意静态方法相比,更喜欢类。您在这里描述的方法听起来像是属于Inventory类,而不是与某个特定实例无关的静态方法。ref float currentAmount应该是类的成员,而不是方法的显式参数。
检查一下你的代码。这将迫使您养成良好的C风格习惯,例如用大写字母命名类和方法,以及在get/set方法上使用属性。
您最好使用一个字典,其中使用项的名称为单个项编制索引 从这个意义上讲,您可以简单地继续,而不是搜索项目并保持与您的示例相似
/* Remove ref on dictionary, you're not setting myArray to something else */
static void addToInventory(Dictionary<string, baseItem> myArray, baseItem item, float maxAmount, ref float currentAmount)
{
if (currentAmount + item.getWeight() <= maxAmount)
{
Console.WriteLine("item.Quantity = {0}", item.Quantity);
if (myArray[item.Name] == null)
Console.WriteLine("Adding new item ({0})", item.Name);
else
Console.WriteLine("Item ({0}) already exists", item.Name);
myArray[item.Name] = myArray[item.Name] ?? item;
myArray[item.Name].Quantity += item.Quantity;
currentAmount += item.getWeight();
}
else
{
Console.WriteLine("Inventory full");
}
}
通过让add方法返回“this”,即类型Inventory not void,可以实现这一点
getQuantity只能是“return myArray[item.name].Quantity”,当然你不应该在你的库存类“myArray”中调用字典变量。你最好使用一个字典,在这个字典中你可以使用项目的名称来索引单个项目 从这个意义上讲,您可以简单地继续,而不是搜索项目并保持与您的示例相似
/* Remove ref on dictionary, you're not setting myArray to something else */
static void addToInventory(Dictionary<string, baseItem> myArray, baseItem item, float maxAmount, ref float currentAmount)
{
if (currentAmount + item.getWeight() <= maxAmount)
{
Console.WriteLine("item.Quantity = {0}", item.Quantity);
if (myArray[item.Name] == null)
Console.WriteLine("Adding new item ({0})", item.Name);
else
Console.WriteLine("Item ({0}) already exists", item.Name);
myArray[item.Name] = myArray[item.Name] ?? item;
myArray[item.Name].Quantity += item.Quantity;
currentAmount += item.getWeight();
}
else
{
Console.WriteLine("Inventory full");
}
}
通过让add方法返回“this”,即类型Inventory not void,可以实现这一点
getQuantity将只是“return myArray[item.name].Quantity”,当然,您不应该调用库存类“myArray”中的字典变量。这些行引用的是列表中的同一项
int id = myArray.IndexOf(item);
myArray[id].Quantity += item.Quantity;//Change occurs in this line, item.Quantity becomes the same as myArray[id].Quantity
由于项已经在列表中,所以当您说IndexOf时,会得到另一个引用同一对象的变量。在程序的前面部分,您的逻辑似乎有一个bug,因为项的myArray[id].quantity的数量总是相同的
从您的代码片段来看,您似乎想要创建一个新项目,并确定该类型的项目是否已在列表中。如果是,则将其数量添加到该类型的预先存在的项目中 这些行指的是列表中的同一项
int id = myArray.IndexOf(item);
myArray[id].Quantity += item.Quantity;//Change occurs in this line, item.Quantity becomes the same as myArray[id].Quantity
由于项已经在列表中,所以当您说IndexOf时,会得到另一个引用同一对象的变量。在程序的前面部分,您的逻辑似乎有一个bug,因为项的myArray[id].quantity的数量总是相同的
从您的代码片段来看,您似乎想要创建一个新项目,并确定该类型的项目是否已在列表中。如果是,则将其数量添加到该类型的预先存在的项目中 关于一个不相关的主题,我不明白为什么参数List myArray是ref。我认为ref会允许我传入的列表受到影响。在这种情况下不需要这样做。您应该阅读C中传递的参数。感谢您提供的信息性阅读。然而,我不相信裁判真的改变了什么,但我还是从阅读中学到了很多。从现在开始,我将考虑类型。在一个无关的主题上,我不明白为什么参数列表myArray是ref。我认为ref会允许我传入的列表受到影响。在这种情况下,这是不必要的。您应该阅读C中传递的参数。感谢您提供的信息性阅读。然而,我不相信裁判真的改变了什么,但我还是从阅读中学到了很多。从现在开始,我会考虑类型。是的,如果你关心计数,请使用字典;如果你不关心哈希集,请使用+1。我特别喜欢wrt命名标准指南。令人惊讶的是,好的开发人员经常会让他们的生活变得更轻松,而需要帮助的新手或差的开发人员却不会。是的,如果你关心计数,就使用字典;如果你不关心哈希集,就使用哈希集。+1说得很好-我特别喜欢wrt命名标准指南。令人惊讶的是,好的开发人员经常让他们的生活变得更轻松,而需要帮助的新手或差的开发人员却没有。