现在的位置: 首页 > 综合 > 正文

NET中const和readonly的区别

2013年07月27日 ⁄ 综合 ⁄ 共 2067字 ⁄ 字号 评论关闭

前些天去面试,面试题要求谈谈“const”与“readonly”的区别,说实在的要不是我之前吃过亏还真没辙。

const修饰的是常量,而readonly修饰的是只读域。很显然只读域是赋值后就不能被修改的,常量也不能被修改,那么二者究竟有啥不同呢?

1、“const”与“readonly”的区别

只读域只能在申明时初始化或构造器中初始化,其他地方不能进行赋值操作,只读域可以是实例域也可以是静态域,只读域的类型可以是C#类型的任何类型。const修饰的常量必须在申明的时候赋值,而且要求编译器能够在编译时期计算出这个确定的值,const修饰的常量是静态的,只属于类不属于某个具体的实例,另外const修饰的值的类型也是有限制的,他只能是下列类型之一(或者是能够转换为下列类型的):sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, string, enum类型, 或引用类型,但是能够申明为const的引用类型只能为string或值为null的其他引用类型。

2、“const”与“readonly”修饰值的问题

const常量必须在声明的同时对其进行赋值,并且确保该值在编译时可确定并恒定;而readonly常量则可以根据情况选择在声明的同时对其赋予一个编译时确定并恒定的值,或者将其值的初始化工作交给实例构造函数(instant constructor)完成,其值不一定是编译时恒定。例如:public static readonly string q = DateTime.Now.ToString();但是public const string ce = DateTime.Now.ToString();

3、“const”与“static readonly”的区别在项目中的影响

因为const修饰的常量是静态类型的,那么有些朋友就会问static readonly修饰符是不是就等同于const修饰符呢?

答案是否定的,其实const与static readonly还是有区别的,注意:const修饰的常量要求在编译的时候就能够确定他的数值,而static readonly却不需要,他只需要在运行时能确定值就行。

这两个修饰符在项目开发中有着不同的应用,看下面的两段代码:

namespace ConsoleApplication1
{
    public class Program
    {
        static void Main(string[] args)
        {
            Console.Write(ConsoleApplication4.Program.ce);
        }
    }
}
namespace ConsoleApplication4
{
    public class Program
    {
        public static readonly int ce = 200;
    }
}

运行ConsoleApplication1.exe结果是200(这个大家应该毫无疑问)。接下来有趣的现象将要发生了。

(1)修改public static readonly int ce = 400;编译ConsoleApplication4,运行ConsoleApplication1结果400

接下来修改ConsoleApplication4

namespace ConsoleApplication4
{
    public class Program
    {
        public const int ce = 200;
    }
}
运行ConsoleApplication1.exe结果是200(这个大家应该毫无疑问)。
(2)修改public const int ce = 400;编译ConsoleApplication4,运行ConsoleApplication1结果不是400而是200。
在不重新编译ConsoleApplication1的情况下为什么会出项上面的现象呢?我们看看ConsoleApplication4中使用const时,ConsoleApplication1.dll如下
public class Program
{
    // Methods
    private static void Main(string[] args)
    {
        Console.Write(200);
    }
}
看看吧,ConsoleApplication1.dll中直接将ConsoleApplication4.Program.ce替换成了200。
所以不管ConsoleApplication4中的const常量的值变成什么,只要ConsoleApplication1不重新编译都是200。
对于项目而言,const修饰的值一旦改变,所有引用该工程的工程都需要重新编译,static readonly 修饰的值却不需要。
一般情况下,如果你需要声明的常量是普遍公认的并作为单个使用,例如圆周率,黄金分割比例等。你可以考虑使用const常量,如:public const double PI = 3.1415926;。
如果你需要声明常量,不过这个常量会随着实际的运行情况而决定,那么,readonly常量将会是一个不错的选择。
 

抱歉!评论已关闭.