C#更改列表中的对象

时间:2010-06-03 01:30:52

标签: c# list

我在使用找到的索引更改列表中对象的成员时遇到了一些问题。

所以这是我目前使用的方法:

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。

3 个答案:

答案 0 :(得分:9)

这里发生的事情是myArray[id]item 引用同一个对象List.Contains按引用进行比较,而不是按值进行比较。

所以看起来就像你想要做的那样

if (myArray.Contains(item))
{
    item.Quantity++;
}

表示列表中还有一个项目。

但是,以这种方式使用列表是一种根本上不正确的方法。您应该使用Dictionary或Set来实现O(1)查找。

如果你采用字典路线,你会有类似的东西:

// 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");
}

其他几点说明:

  • 避免ref arguments(除非你知道你在做什么)。没有理由让名称不合适的myArraymyList会有所改进,但inventory将是现场的)作为参考传递。
  • 首选properties方法{。}}。
  • 优先于任意静态方法的类。您在此处描述的方法听起来像是属于 Inventory 类,而不是某个与某个特定实例无关的静态方法。 getXXX()应该是该类的成员,而不是该方法的显式参数。
  • 对代码运行StyleCopMake it a pre-build event。这将迫使您进入良好的C#风格习惯,例如使用大写字母命名类和方法(并使用get / set方法的属性)。

答案 1 :(得分:4)

您最好使用一个词典,在该词典中您使用项目的名称来索引单个项目。

从这个意义上说,你可以直接去

而不是搜索项目(并保持与你的例子相似)。
/* 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");  
    }
}  

我也很想创建你自己的Inventory类(它拥有自己的Dictionary字段),所以你可以进行方法链接,即:。

Inventory i = new Inventory(maxAmount);
float currentItemCount = i.add(item).add(item).add(item).getQuantity(item);

你可以通过让你的add方法返回'this'来实现这一点(即输入Inventory not void)。

getQuantity只是'return myArray [item.name] .Quantity',当然你不应该在Inventory类'myArray'中调用Dictionary变量。

答案 2 :(得分:0)

这些行指的是列表中的相同项目

int id = myArray.IndexOf(item);
myArray[id].Quantity += item.Quantity;//Change occurs in this line, item.Quantity becomes the same as myArray[id].Quantity

由于item已经在列表中,因此当您说IndexOf时,您将获得另一个引用同一对象的变量。您的计划中的逻辑似乎可能存在错误,因为item始终具有相同数量的myArray[id].Quantity

从您的代码段中,您似乎想要创建一个新项目,并确定该项目的类型是否已在列表中。如果是,那么您将其数量添加到该类型的预先存在的项目中。