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

C# .NET中readonly、private set、init与仅get属性的区别解析

C# 10 属性访问修饰符对比与代码有效性分析

首先明确:你给出的代码不完全有效,问题出在public int Id {get;};——这个自动属性仅定义了getter,但后备字段未被初始化,编译器会抛出错误。必须通过字段初始化器(如public int Id {get;} = 0;)或构造函数赋值才能合法。其余属性语法均符合C# 10规范。

下面逐个分析每个属性的特性,结合你的猜测纠正讲解:

1. public int Id {get;};

你的猜测:必须在设计时硬编码定义,且永远无法修改?

  • 语法上不合法,需补充初始化逻辑(字段初始化器或构造函数赋值)。
  • 修正后,该属性是只读属性:只能在初始化阶段(字段初始化器、构造函数)赋值,对象创建完成后无法修改。类比Java中private final int id;搭配public getter,且仅在构造器中初始化的写法。

2. public string Dept {get; set;};

你的猜测:可变——可多次修改?

  • 完全正确。这是标准的读写自动属性,外部任意代码都可以读取和修改属性值,无访问限制。类比Java中常规的private String dept;搭配public getter、setter的写法。

3. public string FirstName {get; readonly set;};

你的猜测:不确定

  • 这是C# 9+支持的语法,readonly set限制setter仅能在类的构造函数或字段初始化器中被调用,外部代码无法修改属性值。
  • 初始化完成后属性值不可变更,效果类似只读属性,但允许在构造器中通过setter语法赋值(如this.FirstName = "Alice";),写法更灵活。类比Java中private final String firstName;,仅允许在构造器中赋值。

4. public string LastName {get; private set;};

你的猜测:不确定

  • private set表示setter的访问权限为私有,只有当前类内部的代码可以调用setter修改属性值,外部仅能读取。
  • 和只读属性的区别是:类内部的任意方法(比如业务逻辑方法)可以随时修改该属性值,而只读属性初始化后完全不可变。类比Java中private String lastName;搭配public getter、private setter的写法。

5. public string DateOfJoining {get; init;};

你的猜测:不可变——仅能在构造函数中设置一次?

  • 不完全准确。init是C# 9引入的初始化 setter,除了构造函数,还允许在对象初始化器中赋值(如new Employee { DateOfJoining = "2024-05-20" }),但对象初始化完成后(构造+初始化器执行完毕),就再也无法修改。
  • 这是一种更灵活的不可变属性定义方式,类比Java中record类型的属性,或通过Builder模式初始化后不可变的字段,但C#的init语法更简洁直接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 13:20:27