博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Const 和 readOnly

Posted on 2006-03-09 15:13  Snapping  阅读(732)  评论(5编辑  收藏  举报
        今天读了一篇微软关于域的讲解,觉得收益匪浅,特别是对于const 和readonly的解释可谓透彻至极.

        概括来讲:一是const 和readonly能修饰的变量类型有不同;二是const修饰的常量是在编译时便被计算出确定的值,并代换到引用该常量的每一个地方,而readonly时在运行时才确定的量--只是在初始化后我们不希望它的值再改变。

       详细来讲:首先该说明一下什么是域。域(Field)又称成员变量(Member Variable),它表示存储位置,是C#中类不可缺少的一部分。域的类型可以是C#中任何数据类型。域分为实例域和静态域。实例域属于具体的对象,为特定的对象所专有。静态域属于类,为所有对象所共用。C#严格规定实例域只能通过对象来获取,静态域只能通过类来获取。域的存取限制集中体现了面向对象编程的封装原则。

       readonly 是只读域,const是不变常量。前者是不能进行写操作,后者是不能被修改,到底有什么区别呢?
只读域只能在初始化(声明初始化和constructor初始化)的过程中赋值,其他地方不能对只读域进行赋值,否则编译器就报错。只读域可以是实例域(对象变量)和静态域(static变量)。只读域可以是c#中任何类型。

        而const修饰的常量必须在声明的同时赋值,而且要求编译器能够在编译时候就能计算出这个确定的值。Const修饰的静态变量不能为对象所获取。const修饰的值类型也有限制,它只能修饰下列类型或者能转化成下列类型的:sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, string, enum类型, 或引用类型。但是引用类型的话除了string或者值为null的,其他都不能在编译时候由编译器计算出确切的值,所以const只能生命string或者值为null的引用类型。但是声明一个null的const引用类型已经没有任何意义了。
  
       综上所述,我们就理解了readonly 和const在修饰的变量类型上有差别。所以当我们需要一个const的常量时,但它的类型又限制了它不能在编译时期被计算出确定的值来,我们可采取将之声明为static readonly来解决,很实用哦。
    
       除了这个区别以外还有一个很大的区别就是readonly的值在运行时确定了,而const修饰的值在编译时就确定了。所以在下面这个问题上就会有很大的区别哦。
//file1.cs
//csc /t:library file1.cs
using System;
namespace MyNamespace1
{
   
public class MyClass1
   
{
     
public static readonly int myField = 10;
    }

}



//file2.cs
//csc /r:file1.dll file2.cs
using System;
namespace MyNamespace2
{
    
public class MyClass1
    
{
       
public static void Main()
       
{
         Console.WriteLine(MyNamespace1.MyClass1.myField);
       }

    }

}



我们的两个类分属于两个文件file1.cs 和file2.cs,并分开编译。在文件file1.cs内的域myField声明为static readonly时,如果我们由于某种需要改变了myField的值为20,我们只需重新编译文件file1.cs为file1.dll,在执行file2.exe时我们会得到20。但如果我们将static readonly改变为const后,再改变myField的初始化值时,我们必须重新编译所有引用到file1.dll的文件,否则我们引用的MyNamespace1.MyClass1.myField将不会如我们所愿而改变。这在大的系统开发过程中尤其需要注意。实际上,如果我们能够理解const修饰的常量是在编译时便被计算出确定的值,并代换到引用该常量的每一个地方(是不是可以理解为宏代换呢?),而readonly时在运行时才确定的量--只是在初始化后我们不希望它的值再改变,我们便能理解C#设计者们的良苦用心,我们才能彻底把握const和readonly的行为!