对于readonly和const,很多人无法具体区分,不清楚它们的具体使用场合;现在我们分析它们之间的区别和使用场合。

const是一个编译期常量;const只能用于修饰基元类型、枚举类型或者字符串类型,具有局限性;

因为const是编译期常量,所以const天然就是static的,不用手动的为其增加static修饰符,例如:

static const int ConstValue = ;

编译时,将会提示“常量 ConstValue不能标记为static”;

const最大的优点在于 “效率”,这也是使用const的理由,之所以说const效率高,是因为它在经过编译器编译后,我们在代码中引用const变量的地方会用const变量所对应的实际的值来代替,例如:

Console.WriteLine(ConstValue);

其实代码生成的IL代码则为

Console。WriteLine();

此时程序将不再通过变量来寻找对应的值。

然而readonly是一个运行时常量,并且readonly可以修饰任何类型,没有限制,其赋值行为发生在运行时,readonly的全部意义在于,它在运行时第一次被赋值后将不可以改变,当然了,这个可以分为两个意思

1.对于值类型变量,值本身不可改变

2.对于引用类型变量,引用本身不可改变(指针不可改变)

先说说值类型,例如:

    class Employee {
public readonly int ReadOnlyNumber; public Employee(int value) {
ReadOnlyNumber = value;
}
}

Employee的实例ReadOnlyNumber在构造方法中被赋值,之后将不可改变,例如

            Employee emp = new Employee();
emp.ReadOnlyNumber = ;

此代码将无法通过编译,提示“无法对只读字段赋值(构造函数或者变量初始值指定项中除外)”;

针对于引用类型变量,我们可以做如下的修改

    class Boss {
public string Name { get; set; }
} class Employee2
{
public readonly Boss ReadOnlyBoss; public Employee2(Boss value)
{
ReadOnlyBoss = value;
}
}

Employee2的ReadOnlyBoss是一个引用类型变量,在其被赋值后,变量不能再指向任何其他的Boss实例;例如

            Employee2 emp2 = new Employee2(new Boss() { Name="Witt"});
emp2.ReadOnlyBoss = new Boss() { Name = "Witt2" };

这段代码将无法编译成功,因为ReadOnlyBoss不能在赋值后再指向任何其他的实例。

但是呢,之前我们说过,引用本身不可改变,但是引用所指向的实例的属性值却可以随意修改,例如下面这段代码将可以通过

            Employee2 emp2 = new Employee2(new Boss() { Name="Witt"});
//emp2.ReadOnlyBoss = new Boss() { Name = "Witt2" };
emp2.ReadOnlyBoss.Name = "Witt2";

readonly所代表的运行时含义有一个重要的作用,就是可以为每一个类的实例指定一个readonly的变量,我们以前面的Employee来举例说明;

            Employee e1 = new Employee();
Employee e2 = new Employee();
Employee e3 = new Employee();
Employee e4 = new Employee();
Employee e5 = new Employee();

在这里,每个实例都生成了自己的readonly变量,这也就是readonly的优点。

好了,说了这么多,相信大家也都明白了,const的优点在于效率,但却没有readonly灵活,在程序对效率的要求并不高时(效率的地位不高),readonly则成为你更好的选择,因为readonly没有更多的灵活性。

现在说一下注意点,之前我说过readonly在赋值之后将不能被再次赋值,这是错误的,下面这个例子将很好的说明这一点

    class Employee {
public readonly int ReadOnlyNumber = 50;
public Employee(int value) {
ReadOnlyNumber = value;
ReadOnlyNumber += ;
ReadOnlyNumber *= ;
}
}

ReadOnlyNumber在初始化器中被赋值为50,后来,在构造中又被多次赋值;实际上,我们可以将初始化器理解成构造方法的一部分,在构造方法中,我们确实可以多次对ReadOnlyNumber赋值。

DEMO下载

Readonly与const初识的更多相关文章

  1. 我所理解的readonly和const

    最近要给学校软件小组新成员讲几次课,所以把很多以前懒得学习的和模糊不清的知识点,重新学习了一下. MSDN是这样解释的: readonly 关键字与 const 关键字不同. const 字段只能在该 ...

  2. readonly与const

    readonly与const 在C#中,readonly 与 const 都是定义常量,但不同之处在于:readonly 是运行时常量,而 const 是编译时常量. ; public void Te ...

  3. 配置文件App.config的使用以及Readonly与Const的对比

    以前我们学习的时候都把连接数据库的连接字符串写在一个类中,因为我们的数据库都在自己电脑上.如果更换数据库地址,需要更改这个类,然后重新编译才可以连接到数据库.现在我们需要将连接字符串当道一个文件中,然 ...

  4. Usage of readonly and const

    Many new learners can not make sure the usage scenarios of readonly and const keywords. In my opinio ...

  5. readonly和const的区别

    readonly与const的区别1.const常量在声明的同时必须赋值,readonly在声明时可以不赋值2.readonly只能在声明时或在构造方法中赋值(readonly的成员变量可以根据调用不 ...

  6. c#:readonly与const的区别

    readonly与const的区别: 1.初始化:const  字段只能在该字段的声明中初始化. readonly  字段可以在声明或构造函数中初始化. 2.值: const 字段是编译时常量(con ...

  7. C#中的readonly跟const用法小结

    总结一下常量和只读字段的区别: 由来: 笔者也是在看欧立奇版的<.Net 程序员面试宝典>的时候,才发现自己长久以来竟然在弄不清出两者的情况下,混用了这么长的时间.的确,const与rea ...

  8. [C#] readonly vs const

    C#中的readonly和const两个关键字都可以用来定义系统变量,那两者之间有什么区别呢? 1. const变量赋值后,就不可以对其进行修改.且在定义时就需要给它赋值,使用const修饰的变量是s ...

  9. 编写高质量代码改善C#程序的157个建议——建议6: 区别readonly和const的使用方法

    建议6: 区别readonly和const的使用方法 很多初学者分不清readonly和const的使用场合.在我看来,要使用const的理由只有一个,那就是效率.但是,在大部分应用情况下, “效率” ...

随机推荐

  1. MVC中前台如何向后台传递数据------$.get(),$post(),$ajax(),$.getJSON()总结

    一.引言 MVC中view向controller传递数据的时候真心是一个挺让人头疼的一件事情.因为原理不是很懂只看一写Dome,按葫芦画瓢只能理解三分吧. 二.解读Jquery个Ajax函数 $.ge ...

  2. 华为OJ:字符串合并处理

    字符串合并处理 按照指定规则对输入的字符串进行处理. 详细描述: 将输入的两个字符串合并. 对合并后的字符串进行排序,要求为:下标为奇数的字符和下标为偶数的字符分别从小到大排序.这里的下标意思是字符在 ...

  3. Android 软键盘弹出时把布局顶上去,控件乱套解决方法

    解决办法:方法一:在你的activity中的oncreate中setContentView之前写上这个代码getWindow().setSoftInputMode(WindowManager.Layo ...

  4. dwz ie10一直提示数据加载中

    dwz js资源jquery.validate.js 搜索 this.attr('novalidate', 'novalidate'); 在33行左右 用if (typeof (Worker) !== ...

  5. vc 6.0 连接数据库

    在mysql的文档(C:\Program Files\MySQL\MySQL Server 5.5\lib)里面找到libmysql.dll和libmysql.lib 两个文件,将他们移到 工程文件下 ...

  6. sizeof()与strlen()的区别

    首先需要说明的是sizeof和strlen都可以求长度,但是却有很大的区别,简单来说可以概括为以下几点: 1.sizeof是一个关键字,而strlen确实一个函数. 2.sizeof求的是字节长度,而 ...

  7. 17.allegro导入导出[原创]

    一.从一张现成的PCB中导出元件封装到库中 --- -- 二. ①规则 ②元件摆放位置信息导出 这个时候我们在新建的电路板上: ① 导入记事文档 -- -- 到如后: 系统本来默认的是双层,这个时候变 ...

  8. debian系统安装Thinkpad T410s的无线网卡驱动:centrino Advanced-N 6200 2x2 AGN

    前几天搞到手一台小黑:T410s.自带系统是win7.由于想学习debian,所以就搞成了双系统,安装了一套debian 6.0. 可是让我困惑的是在debian下,无法使用T410s的网卡,因为默认 ...

  9. objective-c 与 js之间传递中文乱码

    最近在做关于js改写oc framework的小project,遇到了不少问题 其中刚遇到的是关于如何在两者之间传递中文字符,带特殊字符的URL字符串 不会很详细的介绍太多,以后会回头做个总结 oc传 ...

  10. pl/sql programming 03 语言基础

    PL/SQL 块结构 最小的有意义的代码单元叫做 块(block). 一个块是一组代码, 这个块给出了执行边界, 也为变量声明和异常处理提供了作用范围, pl/sql 准许我们创建匿名块和命名块, 命 ...