You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 14:47:07