C# Dictionary.Add方法异常:新增元素覆盖已有元素值排查
Dictionary添加元素后已有值被覆盖问题排查与解决
问题现象
使用C# Dictionary.Add方法时,以ParcelID为键、TaxParcel对象为值向集合添加元素,每次新增元素后,所有已存在记录的值都会被最后添加的TaxParcel对象的值覆盖,但键保持正确。
测试代码
namespace DictionaryCollection_test_bed { using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DictionaryCollection_test_bed { class Program { static void Main(string[] args) { //Set up Dictionary Collection and instantiate TaxParcel class Dictionary<string, TaxParcel> ParcelData = new Dictionary<string, TaxParcel>(); TaxParcel ParcelPair = new TaxParcel(); ParcelPair.ParcelID = "1"; ParcelPair.Owner = "Owner1"; ParcelPair.Address = "Address1"; ParcelData.Add(ParcelPair.ParcelID, ParcelPair); //this record is correct at this point //Key ="1", ParcelID = "1", Owner = "Owner1", Address = "Address1" ParcelPair.ParcelID = "2"; ParcelPair.Owner = "Owner2"; ParcelPair.Address = "Address2"; ParcelData.Add(ParcelPair.ParcelID, ParcelPair); //Record 1 now has parcel2 values but still with key 1 //Key ="1", ParcelID = "2", Owner = "Owner2", Address = "Address2" //Record 2 has the correct values for the record //Key ="2", ParcelID = "2", Owner = "Owner2", Address = "Address2" } } //Class declaration public class TaxParcel { public string ParcelID { get; set; } public string Owner { get; set; } public string Address { get; set; } } } }
测试场景说明
- 首次添加键为"1"的
TaxParcel对象后,记录正常; - 修改同一对象属性并添加键为"2"的元素后,键"1"对应的对象值被覆盖为键"2"的对象值,键保持不变;
- 添加更多元素时,所有已有记录的值都会被最后一个元素的值覆盖。
问题根源
TaxParcel是引用类型,代码中仅创建了一个TaxParcel实例ParcelPair,每次修改它的属性后添加到字典,实际上字典中所有键指向的都是同一个内存地址的对象。当你修改这个对象的属性时,所有指向它的引用都会读取到更新后的内容。
解决方案
每次添加新元素时,创建新的TaxParcel实例,避免复用同一个对象。
修改后的代码示例
namespace DictionaryCollection_test_bed { using System; using System.Collections.Generic; class Program { static void Main(string[] args) { Dictionary<string, TaxParcel> ParcelData = new Dictionary<string, TaxParcel>(); // 创建第一个独立实例 TaxParcel parcel1 = new TaxParcel(); parcel1.ParcelID = "1"; parcel1.Owner = "Owner1"; parcel1.Address = "Address1"; ParcelData.Add(parcel1.ParcelID, parcel1); // 创建第二个独立实例 TaxParcel parcel2 = new TaxParcel(); parcel2.ParcelID = "2"; parcel2.Owner = "Owner2"; parcel2.Address = "Address2"; ParcelData.Add(parcel2.ParcelID, parcel2); } } public class TaxParcel { public string ParcelID { get; set; } public string Owner { get; set; } public string Address { get; set; } } }
更简洁的写法(对象初始化器)
Dictionary<string, TaxParcel> ParcelData = new Dictionary<string, TaxParcel>(); ParcelData.Add("1", new TaxParcel { ParcelID = "1", Owner = "Owner1", Address = "Address1" }); ParcelData.Add("2", new TaxParcel { ParcelID = "2", Owner = "Owner2", Address = "Address2" });
内容的提问来源于stack exchange,提问作者Charles Fleischmann
相关产品推荐
相关产品推荐

