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

C#中将数组元素赋值给变量后变量值随数组变动问题如何解决

问题本质

你用到的Clone()、CopyTo都属于数组的浅拷贝操作。由于PremiumBill是引用类型,数组中存储的只是对象在堆内存中的引用地址,浅拷贝仅会复制这些引用地址,不会创建新的PremiumBill对象实例。因此无论你从原数组还是克隆后的数组中取值,得到的x都指向同一个对象,只要原对象的属性被修改,x的取值自然会同步变化。

解决方案

无需克隆整个数组,只需要在取到目标对象后,单独对PremiumBill对象做深拷贝即可,常见实现方式如下:

  • 手动实现深拷贝方法
    在PremiumBill类中新增自定义拷贝方法,逐一复制所有属性值,如果存在嵌套的引用类型属性,需要对嵌套属性也做深拷贝处理:
    public class PremiumBill
    {
        public DateTime PostingDate { get; set; }
        // 其余自定义属性...
    
        public PremiumBill DeepClone()
        {
            return new PremiumBill
            {
                PostingDate = this.PostingDate,
                // 依次赋值所有需要保留的属性
                // 若存在引用类型属性,需调用对应类的深拷贝方法
            };
        }
    }
    
    取值时直接调用该方法即可:
    PremiumBill x = list.OrderBy(j => j.PostingDate)
                        .FirstOrDefault(j => j.PostingDate >= input.PostingDate)
                        ?.DeepClone();
    
  • 序列化反序列化实现通用深拷贝
    如果PremiumBill属性较多、嵌套结构复杂,可以用序列化反序列化的方式快速实现深拷贝,不需要手动编写每个属性的复制逻辑,示例用.NET内置的System.Text.Json实现:
    var source = list.OrderBy(j => j.PostingDate).FirstOrDefault(j => j.PostingDate >= input.PostingDate);
    PremiumBill x = source == null ? null : JsonSerializer.Deserialize<PremiumBill>(JsonSerializer.Serialize(source));
    
    注意:该方案要求PremiumBill包含无参构造函数,且所有需要复制的属性支持序列化。
  • 用record类型快速创建副本(.NET 5+支持)
    若你的项目运行环境为.NET 5及以上版本,可以将PremiumBill定义为record类型,直接通过with表达式快速生成对象副本:
    // 类型定义
    public record PremiumBill(DateTime PostingDate /* 其余属性参数 */);
    
    // 取值逻辑
    var source = list.OrderBy(j => j.PostingDate).FirstOrDefault(j => j.PostingDate >= input.PostingDate);
    PremiumBill x = source with { };
    

内容的提问来源于stack exchange,提问作者Hadi Haidar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 20:27:01