C# const和readonly的区别

本文详细比较了C#中的const和readonly两种定义常量的方式,包括它们的定义方式、类型限制、内存消耗等,并讨论了使用场景及潜在问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在C#中定义常量的方式有两种,一种叫做静态常量(Compile-time constant),另一种叫做动态常量(Runtime constant)。前者用“const”来定义,后者用“readonly”来定义。
   对于静态常量(Compile-time constant),它的书写方式如下:
   public const int MAX_VALUE = 10;
  为什么称它为静态常量呢,因为如上声明可以按照如下理解(注意:如下书写是错误的,会出编译错误,这里只是为了方便说明)。
   public static const int MAX_VALUE = 10;
  用const定义的常量,对于所有类对象而言都是一样的,因此需要像访问静态成员那样去访问const定义的常量,而用对象的成员方式去访问会出变异错误。此外,对于静态常量的访问在编译的时候,是用常量的值去替换常量,例如:
   int nValue = MAX_VALUE;
  这句在编译之后,和如下这句所产生的中间语言代码是一样的。
   int nValue = 10;
  不过,在用const来定义常量的时候,在类型上有很多限制。首先,此类型必须属于值类型,同时此类型的初始化不能通过new来完成,因此一些用struct定义的值类型常量也不能用const来定义。
  相对于const而言,用readonly来定义常量要灵活的多,它的书写方式如下:
   public readonly int MAX_VALUE = 10;
  为什么称为动态变量,因为系统要为readonly所定义的常量分配空间,即和类的其他成员一样拥有独立的空间。此外,readonly所定义的常量除了在定义的时候可以设定常量值外,还可以在类的构造函数中进行设定。由于readonly所定义的常量相当于类的成员,因此使用const来定义常量所受到的类型限制,在使用readonly去定义的时候全部消失,即可以用readonly去定义任何类型的常量。
  综合上面所述,至于对比两者之间的区别具体如下。静态常量(Compile-time constant) 动态常量(Runtime constant)定义声明的同时要设置常量值。声明的时候可以不需要进行设置常量值,可以在类的构造函数中进行设置。类型限制首先类型必须属于值类型范围,且其值不能通过new来进行设置。没有限制,可以用它定义任何类型的常量。对于类对象而言对于所有类的对象而言,常量的值是一样的。对于类的不同对象而言,常量的值可以是不一样的。内存消耗 无。要分配内存,保存常量实体。综述性能要略高,无内存开销,但是限制颇多,不灵活。灵活,方便,但是性能略低,且有内存开销。
  对于在定义常量的时候,到底是用const来定义还是readonly来定义,我以前为了追求性能,因此尽量用const来定义。但是在此书中,提到了一个关于使用const会产生潜在的bug。就是在程序中使用DLL类库某个类的静态常量时,如果在类库中修改静态常量的值,其它接口没有发生变化,一般来说,程序调用端是不需要重新编译,直接执行就可以调用新的类库。不过就是在此情况下,会产生潜在的bug。这是由于静态常量在编译的时候,是用它的值去替换常量,因此在调用端的程序也是这样进行替换的。
  例如:在类库中定义了一个静态常量,如下: public const int MAX_VALUE = 10;
  那么对于程序中调用此静态常量这段代码,在编译后产生的中间语言代码中,是用10来进行替换,即使用静态常量的地方,改为10了。
   那么当类库的静态变量发生变化后,例如: public const int MAX_VALUE = 15;
  那么对于调用端程序是可以在没有重新编译的情况下进行运行,不过此时程序的中间语言代码对应于静态变量的值是10,而不是新类库中的15。因此这样产生的不一致,程序会引发潜在的bug。解决此类问题的方法,就是调用端程序在更新类库之后重新编译一下,即生成新的中间语言代码。
  对于如上在const定义常量时所存在的潜在bug,在用readonly定义常量时是不会发生的。因为readonly定义的常量类似于类的成员,因此在访问的时候需要根据具体常量地址来访问,从而避免此类bug。
  鉴于此,建议用readonly来替换const去定义常量。

转载于http://www.programbbs.com/doc/5360.htm

 

C# const和readonly的区别(收藏于网络)

const readonly 的区别,总是不太清楚,于是查了查资料。

  const 的概念就是一个包含不能修改的值的变量。
常数表达式是在编译时可被完全计算的表达式。因此不能从一个变量中提取的值来初始化常量。
如果 const int a = b+1;b是一个变量,显然不能再编译时就计算出结果,所以常量是不可以用变量来初始化的。


  readonly 允许把一个字段设置成常量,但可以执行一些运算,可以确定它的初始值。
因为 readonly 是在计算时执行的,当然它可以用某些变量初始化。
readonly 是实例成员,所以不同的实例可以有不同的常量值,这使readonly更灵活。


readonly 关键字与 const 关键字不同。

1. const 字段只能在该字段的声明中初始化。
   readonly 字段可以在声明或构造函数中初始化。因此,根据所使用的构造函数,readonly 字段可能具有不同的值。
2. const 字段是编译时常数,而 readonly 字段可用于运行时常数。
3. const 默认就是静态的,而 readonly 如果设置成静态的就必须显示声明。
4.const 对于引用类型的常数,可能的值只能是 stringnull
   readonly可以是任何类型

* 需要注意的一个问题是:

对于一个 readonlyReference 类型,只是被限定不能进行赋值(写)操作而已。而对其成员的读写仍然是不受限制的。

public static readonly Class1 my = new Class1();

my.SomeProperty = 10;
//正常
my = new Class1(); //出错,该对象是只读的

但是,如果上例中的 Class1 不是一个 Class 而是一个 struct,那么后面的两个语句就都会出错。

static readonly:

Java 中 static 是当载入一个类时执行一次的。

C#中是怎么执行的,我没有查到。很奇怪几乎每本java的书都会说static的问题,C#的往往只说怎么用,但是应该是在main函数调用之前初始化,所以static readonly也是运行时的,可以用变量付值,如:

private static readonly string path = System.Windows.Forms.Application.StartupPath + “aaa”;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值