c# const与readonly.doc_第1页
c# const与readonly.doc_第2页
c# const与readonly.doc_第3页
c# const与readonly.doc_第4页
c# const与readonly.doc_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

c# const与readonly本文由sndnnlfhvk贡献 doc文档可能在WAP端浏览体验不佳。建议您优先选择TXT,或下载源文件到本机查看。 我们都知道,const 和 static readonly 的确很像:通过类名而不是对象名进行访问,在程序中 只读等等.在多数情况下可以混用.二者本质的区别在于,const 的值是在编译期间确定的, 因此只能在声明时通过常量表达式指定其值.而 static readonly 是在运行时计算出其值的, 所以还可以通过静态构造函数来赋值. 明白了这个本质区别, 我们就不难看出下面的语句中 static readonly 和 const 能否互换了: 1. static readonly MyClass myins = new MyClass(); 2. static readonly MyClass myins = null; 3. static readonly B = 10; static readonly A = B * 20; 4. static readonly int constIntArray = new int 1, 2, 3; 5. void SomeFunction() const int a = 10; 6.private static string astr=abcd; private const string str = astr+efg; 1:不可以换成 const.new 操作符是需要执行构造函数的,所以无法在编译期间确定 2:可以换成 const.我们也看到,Reference 类型的常量(除了 String)只能是 Null. 3:可以换成 const.我们可以在编译期间很明确的说,A 等于 200. 4:不可以换成 const.道理和 1 是一样的,虽然看起来 1,2,3 的数组的确就是一个常量. 5:不可以换成 readonly,readonly 只能用来修饰类的 field,不能修饰局部变量,也不能修 饰 property 等其他类成员. 6.错误:如果在 astr 前加上 const 或者 const 改为 readonly 即可; 总结:1.const,readonly 和 static readonly 定义的常量,指定初始值后(包括在构造函数内指 定的初始值) 将不可更改,可读不可写; 2.const 定义时必须指定初始值,而 readonly 定义时可以不进行初始化(MS 建议在 定义时初始值),同时也可以在构造函数内指定初始值, 并以构造函数内指定的值为准; 3.const 和 static readonly 定义的常量是静态的,只能由类直接访问;而 readonly 定 义的常量是非静态 的,只能由实例对象访问; 4.static readonly 常量, 如果在构造函数内指定初始值, 则必须是静态无参构造函数; 5.const 是编译时常量,readonly 是运行时常量;cosnt 较高效,readonly 较灵活.在 应用上以 static readonly 代替 const,以平衡 const 在灵活性上的不足, 同时克服编译器优化 cosnt 性能,所带来的程序集引用不一致问题; 文章 2: readonly 和 const 比较 前天犯了个低级错误,是关于 readonly 的,总结了一下: C#的 readonly 关键字只能在字段上面使用 public readonly TcpClient client; 不能在类,方法,属性上面使用 readonly! 顺便看了一下 readonly 和 const 的区别: 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 的值具有只读特性. 有关字符串恒定性的内容,可以参考Microsoft .NET 框架程序设计(修订版). Examples: using System; public class Order public Order() Guid guid = Guid.NewGuid(); ID = guid.ToString(D); / 对于每一份订单,其订单序号都是实时确定的常量. public readonly string ID; public override string ToString() return Order ID: + ID; Explaintion: 如果结合数据库使用,ID field 通常都会都会与某个表的主健(primary key)关联起来,如 Orders 表的 OrderID. 数据库的主健通常采用以下三种方式: 自动递增值.你可以通过把 DataColumn.AutoIncrement 设定为 true 值来激活自动递增特性. 唯一名称.这个是使用自己定义的算法来生成一个唯一序列号. GUID(全局唯一标识符) .你可以通过 System.Guid 结构来生成 GUID,如上例. using System; class Customer public Customer(string name, int kind) m_Name = name; m_Kind = kind; public const int NORMAL = 0; public const int VIP = 1; public const int SUPER_VIP = 2; private string m_Name; public string Name get return m_Name; private readonly int m_Kind; public int Kind get return m_Kind; public override string ToString() if(m_Kind = SUPER_VIP) return Name: + m_Name + SuperVip; else if(m_Kind = VIP) return Name: + m_Name + Vip; else return Name: + m_Name + Normal; Remarks: 一般情况下,如果你需要声明的常量是普遍公认的并作为单个使用,例如圆周率,黄金分割 比例等.你可以考虑使用 const 常量,如:public const double PI = 3.1415926;.如果你需要 声明常量,不过这个常量会随着实际的运行情况而决定,那么,readonly 常量将会是一个不 错的选择,例如上面第一个例子的订单号 Order.ID. 另外,如果要表示对象内部的默认值的话,而这类值通常是常量性质的,那么也可以考虑 const.更多时候我们对源代码进行重构时(使用 Replace Magic Number with Symbolic Constant) ,要去除魔数(Magic Number)的影响都会借助于 const 的这种特性. 对于 readonly 和 const 所修饰的变量究竟是属于类级别的还是实例对象级别的问题,我们先 看看如下代码: Using directives#region Using directives using System; using System.Collections.Generic; using System.Text; #endregion namespace ConstantLab class Program static void Main(string args) Constant c = new Constant(3); Console.WriteLine(ConstInt = + Constant.ConstInt.ToString(); Console.WriteLine(ReadonlyInt = + c.ReadonlyInt.ToString(); Console.WriteLine(InstantReadonlyInt = + c.InstantReadonlyInt.ToString(); Console.WriteLine(StaticReadonlyInt = Constant.StaticReadonlyInt.ToString(); Console.WriteLine(Press any key to continue); Console.ReadLine(); + class Constant public Constant(int instantReadonlyInt) InstantReadonlyInt = instantReadonlyInt; public const int ConstInt = 0; public readonly int ReadonlyInt = 1; public readonly int InstantReadonlyInt; public static readonly int StaticReadonlyInt = 4; 使用 Visual C#在 Main()里面使用 IntelliSence 插入 Constant 的相关 field 的时候,发现 ReadonlyInt 和 InstantReadonlyInt 需 要 指 定 Constant 的 实 例 对 象 ; 而 ConstInt 和 StaticReadonlyInt 却要指定 Constant class 参见上面代码) 可见, const 或者 static readonly ( . 用 修饰的常量是属于类级别的; readonly 修饰的, 而 无论是直接通过赋值来初始化或者在实例 构造函数里初始化,都属于实例对象级别. 一般情况下,如果你需要表达一组相关的编译时确定常量,你可以考虑使用枚举类型 (enum) ,而不是把多个 const 常量直接嵌入到 class 中作为 field,不过这两种方式没有绝对 的孰优孰劣之分. using System; enum CustomerKind SuperVip, Vip, Normal class Customer public Customer(string name, CustomerKind kind) m_Name = name; m_Kind = kind; private string m_Name; public string Name get return m_Name; private CustomerKind m_Kind; public CustomerKind Kind get return m_Kind; public override string ToString() return Name: + m_Name + + m_Kind.ToString() + ; 然而, 当这种结合使用枚举和条件判断的代码阻碍了你进行更灵活的扩展, 并有可能导致日 后的维护成本增加,你可以代之以多态,使用 Replace Conditional with Polymorphism 来对代 码进行重构. (有关多态的详细介绍,请参见今天你多态了吗?一文. ) Comments: readonly field 准确来说应该翻译成为只读域 ,这里是为了统一翻译用语才将它和 const 两者所修饰的量都说成常量 ,希望没有引起误会. 本 文 来 自 CSDN 博 客 , 转 载 请 /powerglover/archive/2009/07/15/4350247.aspx 标 明 出 处 : const 与 readonly const 应该称为常量; readonly 则应称为只读变量. const,readonly,static readonly 定义的常量,指定初始值后(包括在构造 函数内指定初始值)将不可更改,可读不可写. const 常量在定义时必须指定初始值,如:private const string str = 1. 而 readonly 和 static readonly 在声明时可以指定可以不指定初始值,同时也 可以在构造函数内指定初始值,如果同时在声明时和构造函数内指定了初始值, 以构造函数内指定的值为准. const 和 static readonly 定义的常量是静态的,只能由类型直接访问;而 readonly 定义的常量是非静态的,只能由实例对象访问. static readonly 常量,如果在构造函数内指定初始值,则必须是静态无参构造 函数. const 可以定义局部常量和字段常量. const 默认是静态的,只能由类型来访问,不能和 static 同时使用,否则出现 编译错误;readonly 默认是非静态,由实例对象来访问,可以显式使用 static 定义为静态成员. const 只能应用在值类型和 string 类型上, 其他引用类型常量只能定义为 null; readonly 只读字段,可以是任意类型,但是对于引用类型字段来说,readonly 不能限制对该对象实例成员的读写控制. const 必须在字段声明时初始化;而 readonly 可以在声明时,或者构造函数中 进行初始化,不同的构造函数可以为 readonly 常量实现不同的初始值;static readonly 字段只能在声明时,或者静态构造函数中进行初始化. const 可以定义字段和局部变量;readonly 只能定义字段. const 定义时必须初始化;readonly 定义时可以不进行初始化,但是强烈建议在 定义时进行初始化操作. string 类型可以被声明为常量,使得 string 的值具有只读特性. const 常量将直接被编译到引用程序集中,而 readonly 则在动态调用时才获取. 因此在跨程序集的应用系统中,要特别关注 const 常量可能引发的不一致问题. 只读属性提供了对只读变量更好的封装性和更灵活的控制机制, 同时也能够满足 对类型字段只读控制的要求,在使用上,更推荐以只读属性来提供对类型特性的 封装. const 是编译时常量, readonly 是运行时常量, 在应用上, 常以 static readonly 来代替 const. 在 C#中定义常量的方法有两种,一种叫做静态常量(Compile-time constant) ,另一种叫做 动态常量(Runtime constant) .前者用const来定义,后者用readonly来定义. 对于静态常量(Compile-time constant) ,它的书写方法如下: public const int MAX_VALUE = 10; 为啥称它为静态常量呢,由于如上声明能够按照如下理解(留意:如下书写是错误的, 会出编译错误,那里只是为了方便说明) . public static const int MAX_VALUE = 10; 用 const 定义的常量,对于所有类对象而言都是相同的,因此需求像来访静态成员那样 去来访 const 定义的常量,而用对象的成员方法去来访会出变异错误.此外,对于静态常量 的来访在编译的时候,是用常量的值去替换常量,例如: int nValue = MAX_VALUE; 这句在编译之后,和如下这句所产生的中间语句语言代码 Code 是相同的. int nValue = 10; 不过,在用 const 来定义常量的时候,在类别上有很多控制.首先,此类别必需属于值 类别,同时此类别的初始化别经过 new 来完成,因此一部份用 struct 定义的值类别常量也 别用 const 来定义. 相对于 const 而言,用 readonly 来定义常量要灵活的多,它的书写方法如下: public readonly int MAX_VALUE = 10; 为啥称为动态变量,由于操作系统要为 readonly 所定义的常量分配空间,即和类的更 多有联系成员相同拥有独立的空间.此外,readonly 所定义的常量除了在定义的时候能够 设定常量值外,还能够在类的构造参数中停止设定.由于 readonly 所定义的常量相当于类 的成员,因此应用 const 来定义常量所受到的类别控制,在应用 readonly 去定义的时候全 部消失,即能够用 readonly 去定义任何类别的常量. 全面上面所述, 至于对比两者之间的区别具体如下. 静态常量 (Compile-time constant) 动态常量(Runtime constant)定义声明的同时要设置常量值.声明的时候能够不需求停止 设置常量值,能够在类的构造参数中停止设置.类别控制首先类别必需属于值类别范围,且 其值别经过

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论