0

在 .NET Winfroms C# 应用程序中,我有一个名为 listItems 的 Dictionary 集合。我在应用程序启动时将数据存储在其中。在静态类中,我有以下内容:

    // listItems is populated bt reading a file. 
    // No other operations are performed on it, except finding an item.
    public static Dictionary<string, RefItemDetails> itemsList;

   // Find RefItemDetails of barcode
    public static RefItemDetails FindRefItem(string barcode)
    {
        RefItemDetails itemDet = null;
        try
        {
            //if (itemsList.TryGetValue(barcode, out itemDet) == false)
            //    System.Diagnostics.Debug.WriteLine("Barcode " + barcode + " not found in Items");

            //itemDet = itemsList.First(item => item.Key == barcode);//.First(item => item.Barcode == barcode);

            if (itemsList.ContainsKey(barcode) ) 
                itemDet = itemsList[barcode];
        }
        catch (Exception)
        {
            itemDet = null;
        }

        return itemDet;
    }

为了从另一个类的 listItems 中检索项目,我使用:

    refScannedItem = null;
    // Get Unit Barcode & Search RefItem of it
    refScannedItem = UtilityLibrary.FindRefItem(boxItem.UnitBarcode.Trim());

     // Display BOX item details 
     refScannedItem.Barcode = boxItem.BoxBarcode.Trim();
     refScannedItem.Description = "BOX of " + boxItem.Quantity + " " + refScannedItem.Description;
     refScannedItem.Retail *= boxItem.Quantity;
     refScannedItem.CurrentCost *= boxItem.Quantity;

上面发生的情况是,我搜索一个项目并得到它“ refScannedItem”,然后我将它的描述附加到"BOX of " + boxItem.Quantity + " " + refScannedItem.Description;. 因此,如果原始描述是“Aquafina”,我将其设为“BOXof 10 Aquafina”。嵌套时间我扫描相同的产品,我找到了产品,但现在它的描述变成了“10 盒 Aquafina”,所以我的设置描述线变成了“10 盒 10 盒 Aquafina”。类似“10 盒 10 盒 10 盒 Aquafina”等等。

正如您在我的查找代码中看到的那样,我最初使用TryGetValue,然后尝试使用LINQ,然后尝试使用ContainsKey,但在所有这些中,为什么 listItem 的值会被更新。

我知道 asTryGetValueout参数,所以值作为 a 传递reference,然后它将被更改。但listItems[key]也在更新它!我怎样才能避免这种情况发生?我选择了Dictionary集合以便于快速搜索,但这部分在我的应用程序上也带来了很多问题和一个大错误。我找不到接收值但不应该更新的解决方案。所有文章都显示了如何搜索和更新它。

请为上述问题提出解决方案。非常感谢任何帮助。

谢谢

4

5 回答 5

1

您返回一个指向 Dictionary 中包含的项目的指针,因此您对该 Object 所做的任何操作都将存储在原始 Dictionary 对象中。

您要做的是,在 FindRefItem 中,返回一个指向 RefItemDetails 对象副本的指针。

一个简单的方法是编写一个新的构造函数。就像是:

public RefItemDetails(RefItemDetails original)
{
   this.Barcode = original.Barcode ;
   this.Description = original.Description ;
   this.Retail = original.Retail ;
   this.CurrentCost = original.CurrentCost ;
   //Set any other properties here
}

然后替换return itemDet;return new RefItemDetails(itemDet);

于 2015-04-21T13:03:19.393 回答
1

我认为你正在以错误的方式解决这个问题。

您不应该Description在数量发生变化时更新可写属性。

相反,我认为你应该有一个单独的Name属性,其中包含项目的名称(例如 Aquafina)和一个动态创建的只读Description属性,如下所示:

public string Description
{
    get
    {
        return string.Format("Box of {0} {1}", Quantity, Name);
    }
}

或者类似的东西。

于 2015-04-21T13:07:52.720 回答
0

您正在从 Dictionary 中获取一个对象 - 然后对其进行更改,因此它的属性当然也会在 Dictionary 中更改……您还没有克隆它,那么为什么要复制呢?

解决方案很简单,更改项目的值并以不同的方式使用修改后的文本:

var amendedDescription = "BOX of " + boxItem.Quantity + " " + refScannedItem.Description;
于 2015-04-21T13:01:08.620 回答
0

看起来您需要RefItemDetails复制UtilityLibrary.FindRefItem(boxItem.UnitBarcode.Trim())

于 2015-04-21T13:02:03.620 回答
0

这应该可以解决问题:

if (!refScannedItem.Description.StartsWith("BOX of "))
{
    refScannedItem.Description = "BOX of " + boxItem.Quantity + " " + refScannedItem.Description;
}
于 2015-04-21T13:00:08.000 回答