繁体   English   中英

C#更改列表中的对象

[英]C# Changing Objects within a 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来代替。

这里发生的是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参数 (除非您知道自己在做什么)。 这里没有理由将名称不佳的myArraymyList会有所改进,但inventory会很完善)通过作为参考。
  • 优先于getXXX()方法的属性
  • 首选类优于任意静态方法。 您在此处描述的方法听起来像它属于Inventory类,而不是与某个特定实例无关的静态方法。 ref float currentAmount应该是该类的成员,而不是方法的显式参数。
  • 在代码上运行StyleCop 使其成为预构建事件 这将迫使您养成良好的C#风格习惯,例如用大写字母命名类和方法(以及在get / set方法上使用属性)。

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

从这种意义上讲,您不必去搜索Item(并保持与示例相似),而只需

/* 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而不是void)来实现此目的。

getQuantity只是“返回myArray [item.name] .Quantity”,当然,您不应在库存类“ myArray”中调用Dictionary变量。

这些行引用列表中的同一项目

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM