将成员变量声明为只读有哪些好处?它只是为了防止在类的生命周期中有人更改它的值,还是使用这个关键字会导致任何速度或效率的改进?
当前回答
有一种可能的情况是,编译器可以基于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/
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 ;
}
}
}
使用只读标记的另一个有趣的部分是在单例中防止字段初始化。
例如,在csharpdepth的代码中:
public sealed class Singleton
{
private static readonly Lazy<Singleton> lazy =
new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance { get { return lazy.Value; } }
private Singleton()
{
}
}
readonly在保护字段单例不被初始化两次方面起着很小的作用。另一个细节是,对于上述场景,您不能使用const,因为const强制在编译时创建,而单例在运行时创建。
WPF可以带来性能上的好处,因为它不需要昂贵的DependencyProperties。这对于集合尤其有用
不要忘记有一种变通方法,可以使用out参数在任何构造函数之外设置只读字段。
有点乱,但是:
private readonly int _someNumber;
private readonly string _someText;
public MyClass(int someNumber) : this(data, null)
{ }
public MyClass(int someNumber, string someText)
{
Initialise(out _someNumber, someNumber, out _someText, someText);
}
private void Initialise(out int _someNumber, int someNumber, out string _someText, string someText)
{
//some logic
}
进一步讨论请访问:http://www.adamjamesnaylor.com/2013/01/23/Setting-Readonly-Fields-From-Chained-Constructors.aspx
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制Visual Studio的私有字段生成快捷方式?
- 如何使用JSON确保字符串是有效的JSON。网
- AppSettings从.config文件中获取值
- 通过HttpClient向REST API发布一个空体
- 如何检查IEnumerable是否为空或空?
- 自动化invokerrequired代码模式
- 在c#代码中设置WPF文本框的背景颜色
- 在c#中,什么是单子?
- c#和Java中的泛型有什么不同?和模板在c++ ?
- c#线程安全快速(est)计数器
- 如何将此foreach代码转换为Parallel.ForEach?
- 如何分裂()一个分隔字符串到一个列表<字符串>
- 如何转换列表<字符串>列表<int>?
- c#对象列表,我如何得到一个属性的和