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

由来:

笔者也是在看欧立奇版的《.Net 程序员面试宝典》的时候,才发现自己长久以来竟然在弄不清出两者的情况下,混用了这么长的时间。的确,const与readonly 很像,都是将变量声明为只读,且在变量初始化后就不可改写。那么,const与readonly 这两个修饰符到底区别在什么地方呢?其实,这个牵扯出C#语言中两种不同的常量类型:静态常量(compile-time constants)和动态常量(runtime constants)。这两者具有不同的特性,错误的使用不仅会损失效率,而且还会造成错误。

首先先解释下什么是静态常量以及什么是动态常量。静态常量是指编译器在编译时候会对常量进行解析,并将常量的值替换成初始化的那个值。而动态常量的值则是在运行的那一刻才获得的,编译器编译期间将其标示为只读常量,而不用常量的值代替,这样动态常量不必在声明的时候就初始化,而可以延迟到构造函数中初始化。

当你大致了解上面的两个概念的时候,那么就可以来说明const与readonly了。const修饰的常量是上述中的第一种,即静态常量;而readonly则是第二种,即动态常量。那么区别可以通过静态常量与动态常量的特性来说明:

1)const修饰的常量在声明的时候必须初始化;readonly修饰的常量则可以延迟到构造函数初始化

2)const修饰的常量在编译期间就被解析,即常量值被替换成初始化的值;readonly修饰的常量则延迟到运行的时候

此外const常量既可以声明在类中也可以在函数体内,但是static readonly常量只能声明在类中。

一.值的区别:

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

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

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

二.赋值方法区别:

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

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

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

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

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

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

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

  1. public const int x = 10;
  2. public const string a = "s";
  3. public const User CA = null;
  4. public readonly User CANew = new User();
  5. public readonly User animal;
  6. protected static readonly DateTime StartTime;

  

readonly和const都是用来标识常量的。

    • 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,ushort, int,uint,long,ulong, char,float, double,float, bool,decimal, string。
    • object, 数组(Array)和结构(struct)不能被声明为const常量。
    • 一般情况下,引用类型是不能被声明为const常量的,不过有一个例外:string。该引用类型const常量的值可以有两种情况,string或null。其实,string虽然是引用类型,但是.NET却对它特别处理,这种处理叫做字符串恒定性(immutable),使得string的值具有只读特性。

C#中的readonly跟const用法小结的更多相关文章

  1. Spring mvc中@RequestMapping 6个基本用法小结

    Spring mvc中@RequestMapping 6个基本用法小结 小结下spring mvc中的@RequestMapping的用法. 1)最基本的,方法级别上应用,例如: @RequestMa ...

  2. 转:Spring mvc中@RequestMapping 6个基本用法小结

    Spring mvc中@RequestMapping 6个基本用法小结 发表于3年前(2013-02-17 19:58)   阅读(11698) | 评论(1) 13人收藏此文章, 我要收藏 赞3 4 ...

  3. c++ const用法小结

    const用法 1,定义全局变量的内存分配问题 #define  Pi_1  3.14       //使用#define宏 const double Pi_2 = 3.14    //使用const ...

  4. C++ const用法小结 (欢迎大家拍砖)

    C++const 关键字小结 const 是constant的缩写,本意是不变的,不易改变的意思. const 在C++中是用来修饰内置类型变量,自定义对象,成员函数,返回值,函数参数. 一.cons ...

  5. js正则表达式中的问号几种用法小结

    这篇文章主要介绍了js正则表达式中的问号几种用法,比如+?,*?,{2,3}?可以停止匹配的贪婪模式,感兴趣的朋友可以参考下 在表示重复的字符后面加问号,比如+?,*?,{2,3}?可以停止匹配的贪婪 ...

  6. JAVA中字符串函数subString的用法小结

    本篇文章主要是对JAVA中字符串函数subString的用法进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助 String str; str=str.substring(int begi ...

  7. static 与单例模式、auto_ptr与单例模式、const 用法小结、mutable修饰符

    一.static 与单例模式 单例模式也就是简单的一种设计模式,它需要: 保证一个类只有一个实例,并提供一个全局访问点 禁止拷贝  C++ Code  1 2 3 4 5 6 7 8 9 10 11 ...

  8. C#中的readonly与const的比较

    C#中有两种常量类型,分别为readonly(运行时常量)与const(编译时常量),本文将就这两种类型的不同特性进行比较并说明各自的适用场景.工作原理 readonly为运行时常量,程序运行时进行赋 ...

  9. Spring mvc中@RequestMapping 6个基本用法小结(转载)

    小结下spring mvc中的@RequestMapping的用法. 1)最基本的,方法级别上应用,例如: @RequestMapping(value="/departments" ...

随机推荐

  1. Qt中的CSS配置(QDarkStyleSheet)

    QDarkStylesheet gihub地址 https://github.com/ColinDuquesnoy/QDarkStyleSheet

  2. 通过linux核映射驱动访问GPIO

    1. HPS GPIO原理 1.功能方块图 linux内核是通过Linux内核memory-mapped device驱动访问GPIO控制器的寄存器而控制HPS端用户的LED和KEY的.memory- ...

  3. day11_雷神_udp、多进程等

    day11 1.网络编程 1.1 udp协议 client端 import json import socket server_addr = ('127.0.0.1',9090) sk = socke ...

  4. JQuery Mobile - 固定住页面和页脚

    在点击页面空白时候,页眉和页脚会隐藏,在页眉和页脚加入以下代码就可以了: data-tap-toggle ="false" 例子: <div data-role=" ...

  5. Android 实现手写板技术

    Android手写板和涂鸦的功能,代码如下: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/andro ...

  6. webrtc vad小bug

    当channel为5的时候offset为80,再进行下面的操作smallest_values[j + 1]将会越出数组的限界到”第97个“:应该将下图的16改为15 low_value_vector数 ...

  7. LDO和DC-DC的概念,区别及优缺点

    最近在做蓝牙项目的时候,遇到了需要配置这两种不同的供电模式的问题,这里顺便温习一下这种供电方式的概念,做个总结. LDO :LOW DROPOUT VOLTAGE 低压差线性稳压器,故名思意,为线性的 ...

  8. 什么是Spring Boot?

    什么是Spring Boot? Spring Boot是Spring开源组织下的子项目,是Spring组件一站式解决方案,主要是简化了使用Spring的难度,简省了繁重的配置,提供了各种启动器,开发者 ...

  9. JS闭包与JS函数

    先说说在网上看到的一个闭包案例: var add = (function () {var counter = 0;return function () {return counter += 1;}}) ...

  10. odoo开发笔记 -- 字段增加唯一约束

    前台违反约束效果: 后台模型中定义代码: name = fields.Char(string="Name", copy=False) # 流水号 _sql_constraints ...