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 拥有线稿上色优化、图片重绘、人物姿势检测、涂鸦完善等功能

相关推荐
“AI国潮设计-小江”7 小时前
《Python+SDXL实战:用ControlNet精准控制“英歌舞翻糖吐司”构图,附批量生成脚本》
开发语言·人工智能·python·prompt·aigc
wenwen_chao7 小时前
Python学习与开发资源合集:实用技巧与工具推荐
python
for_ever_love__8 小时前
函数——参数、lambda、*args与作用域
python·函数·大模型开发·编程基础
东莞市云毅网络有限公司8 小时前
企业资料时效性判定:Last-Modified、正文日期与版本字段三路交叉
python·sqlite·自动化运维·geo·数据监测
Query*8 小时前
深入浅出LangGraph【一】_基础篇
python·ai·langchain
XiaoMaqqqq8 小时前
市面上正规的IP驱动产业新场景新工具哪家强
运维·python·网络协议·tcp/ip
许彰午9 小时前
01-Oracle数据库简介与版本选择
数据库·oracle
菜鸟~noob2339 小时前
【电子战】第三季预告—波武器与电子系统强力毁伤
开发语言·数据库·matlab·电子战
ShyanZh9 小时前
【Python3基础】19-Socket 与 TCP、UDP 编程
python·网络协议·tcp/ip·udp
惊讶的猫10 小时前
工具选对之后还不够:商城 Agent 的参数与权限治理
开发语言·python