A constant expression is an expression that can be fully evaluated at compile time. Therefore, the only possible values for constants of reference types are string and null.
const string cstr = "hello, world";
const int[] cint = null; //这个没有实际意义。
static readonly 的意思是,编译的时候,并不确认数值,运行的时候才知道,第一次赋值之后,不可再改变。
const的意思是,编译的时候,就确认了。
在性能方面,const一般是编译期间直接直接copy到引用的地方,static readonly仍然是一个变量的引用。所以如果这个变量定义在一个不同的Assembly当中的话,const可以少一个Assembly的Loading过程和变量的间接寻址。
------------------------------------------
- const和readonly的值一旦初始化则都不再可以改写;
- const只能在声明时初始化;readonly既可以在声明时初始化也可以在构造器中初始化;
- const隐含static,不可以再写static const;readonly则不默认static,如需要可以写static readonly;
- const是编译期静态解析的常量(因此其表达式必须在编译时就可以求值);readonly则是运行期动态解析的常量;
- const既可用来修饰类中的成员,也可修饰函数体内的局部变量;readonly只可以用于修饰类中的成员。
---------------------------------------
readonly 关键字是可以在字段上使用的修饰符。当字段声明包括 readonly 修饰符时,该声明引入的字段赋值只能作为声明的一部分发生,或者发生在同一类的构造函数中。
只能在下列上下文中进行只读字段的赋值:
- 当在声明中初始化变量时,例如:
public readonly int y = 5;
- 对于实例字段,在包含字段声明的类的实例构造函数中;或者,对于静态字段,在包含字段声明的类的静态构造函数中。只有在这些上下文中时,将
readonly
字段传递为 out 或 ref 参数才有效。
示例
// cs_readonly_keyword.cs
// Readonly fields
using System;
public class ReadOnlyTest
{
class MyClass
{
public int x;
public readonly int y = 25; // Initialize a readonly field
public readonly int z;
public MyClass()
{
z = 24; // Initialize a readonly instance field
}
public MyClass(int p1, int p2, int p3)
{
x = p1;
y = p2;
z = p3;
}
}
public static void Main()
{
MyClass p1= new MyClass(11, 21, 32); // OK
Console.WriteLine("p1: x={0}, y={1}, z={2}" , p1.x, p1.y, p1.z);
MyClass p2 = new MyClass();
p2.x = 55; // OK
Console.WriteLine("p2: x={0}, y={1}, z={2}" , p2.x, p2.y, p2.z);
}
}
输出
p1: x=11, y=21, z=32 p2: x=55, y=25, z=24
在前面的示例中,如果使用这样的语句:
p2.y = 66; // Error
将收到编译器错误信息:
The left-hand side of an assignment must be an l-value
这与试图将值赋给常数时收到的错误相同。
注意 readonly 关键字与 const 关键字不同。const 字段只能在该字段的声明中初始化。readonly 字段可以在声明或构造函数中初始化。因此,根据所使用的构造函数,readonly 字段可能具有不同的值。另外,const 字段是编译时常数,而 readonly 字段可用于运行时常数,如下例所示:
public static readonly uint l1 = (uint) DateTime.Now.Ticks;