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

C#中构造函数与对象构造的区别是什么?

构造函数与“对象构造”的核心区别(针对C#只读属性)

首先明确两个概念的范围差异:

  • 构造函数:是类/结构体中用于初始化对象的特殊方法,仅能通过new关键字触发调用,是对象初始化的“传统代码块”入口。
  • 对象构造期间:是指从对象开始被创建到完全初始化完成的整个过程,它包含构造函数内部执行的代码,还包括对象初始化器、记录的with表达式、构造函数链调用等场景。

结合两种属性的行为具体说明:

1. 仅get;的只读自动属性

这种属性的赋值权限被严格限制在构造函数内部,哪怕是看起来属于“创建对象”环节的对象初始化器也不允许赋值:

public class Book
{
    public string Title { get; }

    // 合法:构造函数内赋值
    public Book(string title)
    {
        Title = title;
    }
}

// 编译报错:无法对只读属性“Title”赋值(构造函数或变量初始值设定项中除外)
// var book = new Book { Title = "C# in Depth" };

文档描述的“除构造函数外处处不可变”,这里的范围就是严格的构造函数代码块内部,没有扩展到其他初始化场景。

2. get; init;的初始化属性

这种属性的赋值权限覆盖了整个对象构造期间,除了构造函数内部,还支持对象初始化器、记录的with表达式等场景:

public class Book
{
    public string Title { get; init; }

    // 合法:构造函数内赋值
    public Book(string title)
    {
        Title = title;
    }
}

// 合法:对象初始化器属于构造期间
var book = new Book { Title = "C# in Depth" };

// 如果是记录类型,with表达式也合法(属于新对象的构造期间)
public record BookRecord(string Title);
var updatedBook = book with { Title = "Advanced C#" };

文档描述的“仅在对象构造期间可变”,这里的构造期间是更宽泛的对象初始化全流程,只要是在对象未完全创建完成的阶段都能赋值,对象创建完成后(比如赋值给变量后再尝试修改Title)就会报错。

核心总结

构造函数是对象构造期间的一个子集,对象构造期间包含了更多C#提供的便捷初始化语法(对象初始化器、with表达式等)。微软文档的描述正是在区分这两种权限范围:仅get;的属性锁死了构造函数这唯一入口,而get; init;则放开到整个对象初始化的全流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 15:23:11