在.NET Winfroms C#app中,我有一个名为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;
上面发生的是,我搜索一个项目&amp;我得到它“refScannedItem
”,然后按"BOX of " + boxItem.Quantity + " " + refScannedItem.Description;
追加它的描述。因此,如果原始描述是“Aquafina”,我将它变为“BOXof 10 Aquafina”。嵌套时间我扫描相同的产品,我找到了产品,但现在它的描述已经变成了“10盒Aquafina”,所以我的设置描述变成了“10个Aquafina的10个BOX的盒子”。像“10 Aquafina 10 BOX 10 BOX BOX”等等也是如此。
正如你在我的查找代码中看到的那样,我最初使用TryGetValue
,然后尝试使用LINQ
,然后尝试使用ContainsKey
,但在所有这些代码中,为什么值listItem得到更新。
我理解,由于TryGetValue
具有out
参数,因此该值将作为reference
传递,然后它将被切换。但是在listItems[key]
中也会更新它!我怎样才能避免这种情况发生?我选择了Dictionary
收藏以方便和放心快速搜索,但这部分给我的应用程序带来了很多问题和一个大错误。我无法找到接收值但不应更新的nay解决方案。所有文章都展示了如何搜索&amp;更新它。
请建议上述解决方案。任何帮助都非常感谢。
由于
答案 0 :(得分:1)
您返回指向词典中包含的项目的指针,因此您对此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);
答案 1 :(得分:1)
我认为你这样做是错误的。
您不应该有可写的Description
属性,只要数量发生变化,您就会更新。
相反,我认为你应该有一个单独的Name
属性,其中包含项目的名称(例如Aquafina)和动态创建的只读Description
属性,如下所示:
public string Description
{
get
{
return string.Format("Box of {0} {1}", Quantity, Name);
}
}
或类似的东西。
答案 2 :(得分:0)
这应该可以解决问题:
if (!refScannedItem.Description.StartsWith("BOX of "))
{
refScannedItem.Description = "BOX of " + boxItem.Quantity + " " + refScannedItem.Description;
}
答案 3 :(得分:0)
你从字典中获取一个对象 - 然后改变它,所以当然它的属性也会在字典中改变......你还没有克隆它,所以你为什么要服用它副本?
解决方案非常简单 not 来更改项目的值并以不同的方式使用修改后的文本:
var amendedDescription = "BOX of " + boxItem.Quantity + " " + refScannedItem.Description;
答案 4 :(得分:0)
看起来您需要制作RefItemDetails
的副本,以便在从UtilityLibrary.FindRefItem(boxItem.UnitBarcode.Trim())