C#怎么使用with表达式 C#record类型中with表达式怎么用如何创建对象的修改副本【语法】

with表达式仅支持record类型(含record class/struct),不支持普通class或struct;其为浅拷贝,不递归复制引用对象;init setter中调用with易致无限递归,需避免。with 表达式只能用于 record 类型不是所有类都能用 with,只有 record(包括 record class 和 record struct)才支持。普通 class 或 struct 写 obj with { Prop = value } 会直接编译报错:CS8852: Init-only property or indexer 'X' can only be assigned in an object initializer, or on 'this' in an instance constructor。常见错误是把老代码里的类改成 record 时漏掉 record 关键字,或者误以为继承自 record 的子类自动获得 with 能力------其实不行,子类也得显式声明为 record。record 是语法糖,底层靠生成 Clone() + init 属性 + 编译器合成的 With 方法实现如果类型里有非 init 的可变属性(比如只有 set 没有 init),with 表达式不会修改它,也不会报错,容易误以为改成功了record struct 同样支持 with,但要注意值类型的语义:每次 with 都是新副本,原变量不变with 会深拷贝还是浅拷贝?with 表达式只做浅拷贝 ------ 它复制字段值,不递归复制引用对象。如果 record 里有个 List<string> 字段,with 出来的新实例和原实例共享同一个 List 对象。这在多线程或后续修改集合时容易出问题。比如:var r1 = new Person("Alice", new List<string> { "A" });var r2 = r1 with { Name = "Bob" };r2.Hobbies.Add("B"); // r1.Hobbies 也会变成 ["A", "B"]想真正"不可变",嵌套的引用类型字段本身也得是 record 或不可变类型(如 IReadOnlyList<T>、ImmutableArray<T>)没有银弹:如果必须深拷贝,得自己写逻辑,with 不负责、也不支持指定深度with 对 null 字段照常赋值,不会跳过或报空引用异常with 表达式中访问 this 成员要小心循环引用在 with 初始化器里,不能直接用 this.Xxx 引用当前实例成员,因为此时 this 尚未完成构造。但更隐蔽的问题是:如果你在 record 的 init 属性 setter 里又调用了 with,可能触发无限递归。典型场景是带验证逻辑的 init setter: 稿定AI 拥有线稿上色优化、图片重绘、人物姿势检测、涂鸦完善等功能

相关推荐
尚雷55802 小时前
Oracle 多租户架构下常用运维SQL
数据库·sql·oracle
神明9312 小时前
uni-app动画效果实现 uni-app如何使用animation API
jvm·数据库·python
m0_690825822 小时前
uni-app怎么做类似于微博的新消息气泡 uni-app角标动画效果实现【代码】
jvm·数据库·python
m0_631529822 小时前
uni-app iOS后台运行 uni-app App如何实现后台定位或音乐播放
jvm·数据库·python
Mike117.2 小时前
GBase 8c 序列用在业务流水号上要留几道边界
服务器·数据库
2301_779622412 小时前
如何睡眠等待_DBMS_LOCK.SLEEP与DBMS_SESSION暂停当前会话
jvm·数据库·python
皮卡祺q2 小时前
【JVM】:类加载机制,jvm内存布局,垃圾回收,String 不可变性源码分析
java·开发语言·jvm·多线程·string
2303_821287382 小时前
CSS中如何实现绝对定位元素的等比缩放_利用宽高百分比
jvm·数据库·python
java修仙传2 小时前
实习日志:完成算法调用总接口并修复联调问题
java·开发语言·数据库