将成员变量声明为只读有哪些好处?它只是为了防止在类的生命周期中有人更改它的值,还是使用这个关键字会导致任何速度或效率的改进?
当前回答
readonly关键字用于将成员变量声明为常量,但允许在运行时计算值。这与使用const修饰符声明的常量不同,后者必须在编译时设置其值。使用readonly,您可以在声明中或在字段所属对象的构造函数中设置字段的值。
如果您不想重新编译引用该常量的外部dll(因为它在编译时被替换),也可以使用它。
其他回答
有一种可能的情况是,编译器可以基于readonly关键字的存在进行性能优化。
这仅适用于只读字段也标记为静态的情况。在这种情况下,JIT编译器可以假设这个静态字段永远不会改变。JIT编译器在编译类的方法时可以考虑到这一点。
一个典型的例子:你的类可以有一个静态只读的IsDebugLoggingEnabled字段,在构造函数中初始化(例如基于配置文件)。一旦实际的方法被jit编译,当调试日志未启用时,编译器可能会省略代码的整个部分。
我没有检查这个优化是否在当前版本的JIT编译器中实际实现,所以这只是推测。
令人惊讶的是,只读实际上会导致代码变慢,正如Jon Skeet在测试他的Noda Time库时发现的那样。在本例中,一个在20秒内运行的测试在删除readonly后只花了4秒。
https://codeblog.jonskeet.uk/2014/07/16/micro-optimization-the-surprising-inefficiency-of-readonly-fields/
小心使用私有只读数组。如果客户端将这些对象作为对象公开(您可以像我一样为COM互操作这样做),客户端可以操作数组值。当将数组作为对象返回时,请使用Clone()方法。
请记住,readonly只应用于值本身,所以如果您使用引用类型,readonly只保护引用不被更改。实例的状态不受只读保护。
Readonly可以在声明时初始化,也可以只从构造函数中获取它的值。与const不同,它必须同时进行初始化和声明。 Readonly拥有const所拥有的一切,再加上构造函数初始化
代码https://repl.it/HvRU/1
using System;
class MainClass {
public static void Main (string[] args) {
Console.WriteLine(new Test().c);
Console.WriteLine(new Test("Constructor").c);
Console.WriteLine(new Test().ChangeC()); //Error A readonly field
// `MainClass.Test.c' cannot be assigned to (except in a constructor or a
// variable initializer)
}
public class Test {
public readonly string c = "Hello World";
public Test() {
}
public Test(string val) {
c = val;
}
public string ChangeC() {
c = "Method";
return c ;
}
}
}
推荐文章
- 防止在ASP中缓存。NET MVC中使用属性的特定操作
- 转换为值类型'Int32'失败,因为物化值为空
- c#中有任何连接字符串解析器吗?
- 在Linq中转换int到字符串到实体的问题
- 是否可以动态编译和执行c#代码片段?
- 创建自定义MSBuild任务时,如何从c#代码获取当前项目目录?
- c#和Java的主要区别是什么?
- 在c#中创建一个特定时区的DateTime
- .NET中的属性是什么?
- csproj文件中的“Service Include”是干什么用的?
- 如何使用try catch进行异常处理是最佳实践
- 替换字符串中第一次出现的模式
- .NET中字节的字面后缀?
- 如何处理AccessViolationException
- c#忽略证书错误?