关于C#中readonly的变量赋值问题。

const与readonly 很像,都是将变量声明为只读,且在变量初始化后就不可改写。那么,const与readonly 这两个修饰符到底区别在什么地方呢?其实,这个牵扯出C#语言中两种不同的常量类型:静态常量(compile-time constants)和动态常量(runtime constants)。这两者具有不同的特性,错误的使用不仅会损失效率,而且还会造成错误。

      首先先解释下什么是静态常量以及什么是动态常量。静态常量是指编译器在编译时候会对常量进行解析,并将常量的值替换成初始化的那个值。而动态常量的值则是在运行的那一刻才获得的,编译器编译期间将其标示为只读常量,而不用常量的值代替,这样动态常量不必在声明的时候就初始化,而可以延迟到构造函数中初始化。

      当你大致了解上面的两个概念的时候,那么就可以来说明const与readonly了。const修饰的常量是上述中的第一种,即静态常量;而readonly则是第二种,即动态常量。那么区别可以通过静态常量与动态常量的特性来说明:

      1)const修饰的常量在声明的时候必须初始化;readonly修饰的常量则可以延迟到构造函数初始化 

      2)const修饰的常量在编译期间就被解析,即常量值被替换成初始化的值;readonly修饰的常量则延迟到运行的时候

      此外const常量既可以声明在类中也可以在函数体内,但是static readonly常量只能声明在类中。

 

 
  1. <span style="font-size:18px;">class Program

  2. {

  3. class Test

  4. {

  5. public const int constTest = 2;

  6. public readonly int readonlyTest;

  7. //也可以在声明时初始化

  8. //public readonly int readonlyTest=3;

  9. public static readonly int staticReadonlyTest;

  10. //同readonlyTest

  11. public Test()

  12. {

  13. readonlyTest = 3;

  14. //延迟到构造函数中初始化

  15. }

  16. static Test()

  17. {

  18. staticReadonlyTest = 4;

  19. //延迟到构造函数中初始化

  20. //注意:static变量在static构造函数中初始化

  21. }

  22.  
  23. }

  24. static void Main(string[] args)

  25. {

  26. Console.WriteLine("constTest is {0},staticReadonlyTest is {1}", Test.constTest,

  27.  
  28. Test.staticReadonlyTest);

  29. Console.ReadLine();

  30. }

  31. }</span>

 

 相同点:

 

  1.  const与readonly都是只读的.
  2.  const默认是static的,而且在编译期间已经解析完成.所以const与static readonly 只能由类来访问,而readonly由实例来访问.

 

       不同点

 

  1. const既可以修饰类中的成员,又可以修饰函数体中的成员.而readonly只能修改类中的成员.
  2. const(静态常量)只能声明为简单的数据类型,如int,浮点型,枚举,布尔,字符串型.而readonly(动态常量)可以修饰一下对象类型,如Datetime类型.

 

        注意:

  1.  const默认是静态的,不能再static const!
  2.  static readonly常量,如果要在构造函数中初始化其值,必须在静态无参构造函数中初始化.

 

总结:

       const是静态常量,readonly是动态常量.const高效,readonly灵活!但实际开发中我们经常用static readonly 来代替const, 以平衡const在灵活性上的不足.

 

最近看到了readonly和const的区别,发现了一个自己的知识盲区,就是关于readonly的赋值问题。我的理解是对于readonly的一个变量,如果是值类型的,那么是这个变量的写操作是受限制的,如果是一个引用类型,那么保存的是这个变量的内存地址,对这个引用的写操作是受限制的,但是对于这个变量里面的成员的读写操作是不受限制的。具体可以看下面的一个例子。

 

 
  1. using System;

  2. using System.Collections.Generic;

  3. using System.Linq;

  4. using System.Text;

  5. using System.Threading.Tasks;

  6. namespace ConsoleApp1

  7. {

  8. class Program

  9. {

  10. public Program()

  11. {

  12. _testList.Add(123);

  13. }

  14. private readonly List<int> _testList = new List<int>();

  15. static void Main(string[] args)

  16. {

  17. Program pro = new Program();

  18. pro.Test();

  19. Console.ReadKey();

  20. }

  21. private void Test()

  22. {

  23. Console.Write(_testList.Count+“ ”);

  24. _testList.Add(1);

  25. Console.Write(_testList.Count);

  26. }

  27. }

  28. }

 

输出:1  2

可以看到这时候对_testList的添加操作是不受限制的,因为是改变了_testList里面的成员,而对于_testList里面保存的内存地址并没有改变,所以是可以添加的。

如果把 _testList.Add(1); 修改为  _testList = new List<int>;就会有报错,报错为:无法对只读的变量赋值(构造函数或变量初始值指定项中除外)。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#readonly是一个关键字,用于声明只读字段。只读字段是在声明时或构造函数初始化,并且不能在其他地方再次赋值。与const关键字不同,readonly字段可以在字段声明和任何构造函数多次分配不同的值。这使得readonly字段可以在运行时根据需要进行初始化。 例如,可以使用readonly关键字声明一个只读字段,并在构造函数初始化它: ``` public class ReadOnlyDemo { private readonly string _code = "empty string"; public ReadOnlyDemo(string code) { _code = code; } public string GetCode() { return _code; } } ``` 在上面的示例,_code字段是只读的,它在构造函数被初始化,并且不能在其他方法再次赋值。 另外,readonly字段也可以用于运行时常量。这意味着它们可以在运行时被赋值,并且在整个程序的执行过程保持不变。这与编译时常量(const)不同,后者在编译时被赋值并且在整个程序的执行过程保持不变。 例如,下面的示例展示了如何在构造函数初始化只读字段,并在运行时保持不变: ``` public static readonly uint timeStamp = (uint)DateTime.Now.Ticks; ``` 在上面的示例,timeStamp字段是只读的,并且在声明时被初始化为当前时间的刻度数。由于它是只读的,它的值在整个程序的执行过程保持不变。 总结起来,C#readonly关键字用于声明只读字段,这些字段在声明时或构造函数初始化,并且不能在其他地方再次赋值。它们可以在运行时根据需要进行初始化,并且可以用于运行时常量。 #### 引用[.reference_title] - *1* *2* [一看就懂——C#readonly关键字](https://blog.csdn.net/CrazyRock98/article/details/106490654)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [C#——关键字:readonly](https://blog.csdn.net/weixin_43945471/article/details/112473546)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值