C#中的readonly跟const用法小结

来源:互联网 发布:网络机房防雷接地规范 编辑:程序博客网 时间:2024/06/15 21:16

摘自:http://blog.csdn.net/u013930409/article/details/45953481

总结一下常量和只读字段的区别:

一.值的区别:

常量(const):是已知的,不能修改的值。const都是静态的,不能使用static修饰。

只读字段(readonly):不能修改的,只读字段的值不能在编译时确定,而是在运行时确定的。

readonly可以用static修饰,也可以不用。

二.赋值方法区别:

常量(const):只能在声明时赋值,常量的值在编译时就已经确定,在程序中不能改变。

只读字段(readonly):只读字段可以在声明时或者在构造函数内赋值。只读字段可以是静态字段(一个类只有一个值),也可以是实例字段(每一个实例有自己的值)

Const 定义的是静态常在对象初始化的时候赋值.const修饰的常量必须在声明的同时赋值,以后不能改变它的值.属于编译时常量。不能用new初始化。

const修饰的常量为静态变量,不能够为对象所获取

Readonly 是只读变量.属于运行时变量.可以在类constructor里改变它的值.不能作用于局部变量。

(因此被Readonly修饰的变量只能在初始化--声明初始化或构造器初始化--的过程中赋值,其他地方不能进行对只读域的赋值操作)

readonly仅仅用于修饰class的field(字段)

readonlyconst都是用来标识常量的。

  • const可用于修饰class的field或者一个局部变量(local variable);而readonly仅仅用于修饰class的field。
  • const常量的值必定在编译时就已明确并且恒定的;而readonly常量却有一点不同,那就是其值可以在运行时编译,当然,它也必须遵守作为常量的约束,那就是值必须恒定不变。
  • const常量必须在声明的同时对其进行赋值,并且确保该值在编译时可确定并恒定;而readonly常量则可以根据情况选择在声明的同时对其赋予一个编译时确定并恒定的值,或者将其值的初始化工作交给实例构造函数(instant constructor)完成。如:public readonly string m_Now = DateTime.Now.ToString();,m_Now会随着运行时实际情况变化而变化。
  • const常量属于类级别(class level)而不是实例对象级别(instant object level),并且它不能跟static结合一起使用,该常量的值将由整个类的所有实例对象共同分享(详细论述参见后面的Remark区域)。
  • readonly常量既可以是类级别也可以是实例对象级别的,这取决于它的声明以及初始化工作怎么实施。readonly可以与static结合使用,用于指定该常量属于类级别,并且把初始化工作交由静态构造函数(static constructor)完成(有关如何把readonly常量声明为类级别或实例对象级别的论述清参见后面的Remark区域) 。
  • 能被const修饰声明为常量的类型必须是以下的基元类型(primitive type):sbyte,byte,short,ushortint,uintlong,ulongchar,floatdouble,floatbool,decimal,string
  • object, 数组(Array)和结构(struct)不能被声明为const常量。
  • 一般情况下,引用类型是不能被声明为const常量的,不过有一个例外:string。该引用类型const常量的值可以有两种情况,stringnull。其实,string虽然是引用类型,但是.NET却对它特别处理,这种处理叫做字符串恒定性(immutable),使得string的值具有只读特性

例如我们这里有一个类

class TestClass2    {        private int someValue;        public void ChangeValue(int newValue)        {            someValue = newValue;        }        public int ShowValue()        {            return someValue;        }    }

而在另一个类中使用它

class TestClass    {        private readonly TestClass2 tc; // 注意此处tc是readonly的        public TestClass()        {            tc = new TestClass2();        }        public void ChangeTCValue(int value)        {            tc.ChangeValue(value);        }        public void Show()        {            Console.WriteLine("{0}", tc.ShowValue());        }    }

我们看到虽然tc这个字段是readonly的,但是可以使用方法来改变tc中someValue的值。似乎这个“只读”失去了意义,因为可以修改它的值的话还叫什么“只读”呢?

非也!

从上面的代码中我们可以看到,tc的类型是TestClass2,是一个引用类型。而引用类型是必须用new关键字为它分配了一块内存以后它才能在后续代码中工作的。也就是说,tc这个变量仅仅是一块内存地址罢了。

也就是说,这里的“readonly” tc只是无法再重新更改它的引用,但它所引用对象的属性是可以改变的。

那么为什么不用const呢?还是因为tc是引用,是动态分配内存的,不可能在编译阶段就确定它的地址,这点和值类型(包括string)是完全不一样的。

综上所述,可以得出结论: readonly修饰的字段,其初始化仅是固定了其引用(地址不能修改),但它引用的对象的属性是可以更改的。

0 0
原创粉丝点击