C#中为方法/属性返回值标记readonly的语法含义问询
C#中非ref返回值添加readonly修饰符的语法含义
问题背景
在使用Visual Studio 2022(版本17.6.4)时,IDE触发IDE0251规则,建议给部分方法和属性的返回签名添加readonly关键字,但该规则暂无官方文档说明。测试发现以下代码在现有项目可正常编译运行:
属性形式
public readonly bool IsInitialized => component != null;
方法形式
public readonly bool IsInitialized() { return component != null; }
已知ref readonly用于标记返回的引用不可修改,但找不到非ref返回值(如示例中的bool类型)添加readonly的官方说明,且该代码在新.NET 6控制台项目中会编译报错。
语法含义解析
这个readonly修饰符的作用分两种场景,和成员所属的类型(结构体/类)以及使用的C#版本直接相关:
1. 结构体(struct)的成员(C# 8.0及以上支持)
对于结构体的实例方法或属性,readonly表示该成员绝对不会修改结构体的任何实例字段:
- 编译器会强制验证成员内部的代码,如果存在修改结构体实例字段的操作,直接编译报错
- 当在只读上下文(比如
in参数、只读字段)中调用结构体的readonly成员时,编译器可以直接使用结构体的副本,无需创建新实例,能提升性能
2. 类(class)的成员(C# 11.0及以上支持)
C# 11新增了类的只读实例方法特性,readonly修饰符表示该成员不会修改类的任何实例字段(静态字段不受限制):
- 编译器会做静态代码检查,如果方法/属性内部存在修改实例字段的操作,会抛出编译错误
- 这个修饰符属于提示性+约束性的语法,既可以让代码可读性更强(明确该成员是只读操作),也能帮助编译器做一些优化
编译差异原因
- 现有项目能编译:大概率是项目启用了C# 11或更高版本(可通过项目文件中的
<LangVersion>节点查看),或者这些成员所属的类型是结构体 - 新.NET 6项目编译报错:.NET 6默认对应的C#版本是10,不支持类成员添加
readonly修饰符的语法,因此会报错
内容的提问来源于stack exchange,提问作者Brett Woodard
相关产品推荐
相关产品推荐

