码迷,mamicode.com
首页 > Windows程序 > 详细

c# const, static 和readonly关键字的理解

时间:2016-04-09 18:29:35      阅读:226      评论:0      收藏:0      [点我收藏+]

标签:

关于c#的const, static, readyonly关键字修饰成员变量时的区别,下面通过一个简单的例子来说明:

 1 //SomeType.cs
 2 
 3 using System;
 4 
 5 public sealed class SomeType
 6 {
 7     public Int32 Id = 1;
 8 
 9     public const Int32 constId = 100; //IL  .field public static literal int32 constId = int32(0x00000032)
10     
11     public static Int32 staticId = 1000; //IL .field public static int32 staticId
12 
13     public readonly Int32 readonlyId = 2000; //IL .field public initonly int32 readonlyId
14 
15     public readonly Int32[] readonlyArrayId = new Int32[]{1, 2, 3};//readonlyArrayId本身不能再次write, 但是指向的对象可以改变
16 
17     public static readonly Int32 staticReadOnlyId = 5000; //IL .field public static initonly int32 staticReadOnlyId
18 
19     public SomeType()
20     {
21         readonlyId = 20001;
22     }
23 }
 1 //TestSomeType.cs
 2 
 3 using System;
 4 
 5 public class TestConst 
 6 {
 7     public static void Main(String[] args)
 8     {
 9         SomeType someType = new SomeType();
10 
11         //test1
12         int result = someType.Id + SomeType.constId + SomeType.staticId + someType.readonlyId + SomeType.staticReadOnlyId;
13 
14         //test2
15         someType.readonlyArrayId[1] = 4;
16 
17         Console.WriteLine(someType.readonlyArrayId[1]);//output 4
18 
19         //test3
20         Console.WriteLine("constId: " + SomeType.constId);//
21 
22         Console.WriteLine("staticId: " + SomeType.staticId);
23     }
24 }

 一. 结论

1. readonly

  (1) 修饰成员变量的时候,该变量只能通过变量定义时或者早构造方法里面赋值。

      (2) 修饰的成员变量是实例字段,内存是在构造函数类型的实例时分配的。

      (3) 修饰的成员变量是引用类型的时候,不可改变的是引用,引用指向的对象是可以改变的。

2. static

  (1) 修饰的成员变量是类型资源,内存是在类型对象中分配的,和具体的实例无关。

3. const

     (1) 编译成IL代码后由static literal 修饰,由此可见const修饰的变量最终表示成static类型同时被literal修饰( literal修饰的变量必须在变量声明的时候赋值,编译器编译成IL代码时会直接把这个变量的值插入到引用这个变量的位置替代之前的变量,从而程序在运行时不需要再为此变量分配内存)。

 

二. const与static的区别

1. 编译SomeType.cs 和 TestSomeType.cs

//生成SomeType.netmodule
csc /t:module SomeType.cs
 
//生成TestSomeType.exe
csc TestSomeType.cs /addmodule:SomeType.netmodule

 运行TestSomeType.exe 可以看到test3中的输出为:

constId: 100
staticId: 1000

现在改变SomeType.cs类型的constId和staticId的值分别为50, 500,然后重新生成SomeType.netmodule

接着再次运行TestSomeType.exe可以看到test3中输出为:

constId: 100
staticId: 500

结果发现只有staticId的值引用的新值。再来看看TestSomeType.cs类的Main函数的IL代码:

技术分享

可以看到上图的四个标记。标记(1)和(3)是constId编译成IL代码的表示,标记(2)和(4)是staticId编译成IL代码的表示。

对于constId 我们可以发现constId其实已经替换成其对应的值了,所以改变SomeType.cs的constId重新编译影响不到已经编译好的TestSomeType程序集。

对于staticId变量标明的是所在模块的信息,当程序运行起来时CLR会加载其对应的netmodule来获取staticId的值。所以改变SomaeType.cs的staticId的值并重新编译,在TestSomeType程序集中即可获取最新的值。

 

c# const, static 和readonly关键字的理解

标签:

原文地址:http://www.cnblogs.com/elang/p/5371999.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!