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

对象初始化器异常行为:为何可修改只读属性关联对象的属性?

代码运行逻辑与对象初始化语法解析

核心误解:你混淆了两种对象初始化语法

你看到的Test = { Name = "hello" }不是给Test属性赋值,而是C#的嵌套成员初始化语法,它的作用是对已存在的Test实例的成员进行赋值,而非创建新的Test对象赋值给属性。

代码运行完整流程

  1. 构造执行顺序:
    执行new Child()时,会先调用父类Parent的构造函数(子类构造默认隐式调用父类无参构造)。在Parent的构造里,已经创建了一个Test实例,将其Name设为"Default",并赋值给Parent中**只读(get-only)**的Test属性。

  2. 对象初始化块的实际作用:
    构造函数执行完成后,进入对象初始化块{ Test = { Name = "hello" } }。这个语法等价于:

    var tempChild = new Child();
    tempChild.Test.Name = "hello";
    Child child = tempChild;
    

    它并没有试图给Test属性重新赋值(如果这么写Test = new Test { Name = "hello" },会因为Test是get-only属性直接编译报错),而是获取Parent构造已经创建好的Test实例,修改它的Name属性值,把原来的"Default"替换成"hello"。

为什么不会报错?

  • Parent的Test属性是public Test { get; },虽然没有setter,但外部代码可以读取这个属性的实例(因为get是public的)。
  • Test类的Name属性有set方法,所以可以修改它的值。
  • 这种成员初始化语法只需要目标对象已经存在,且成员可访问、可修改,不需要属性有setter。

对比验证

如果改成试图给Test属性赋值,会直接触发编译错误:

Child child = new Child
{
    // 编译报错:Test属性是只读的,无法赋值
    Test = new Test { Name = "hello" }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 22:13:14