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

关于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程序集中即可获取最新的值。

时间: 2024-10-15 11:38:21

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

深入探讨C#中的const、readonly关键字

首先不可否认,这些在面试上会经常被面试官问起,但是你回答的让面试官满意吗?当然如果你知道了这些原理,或许你就不 怕了.既然说到了原理,我们还是从MSDN说起. 一:值得推敲的几个地方 1.先来看看msdn上面对const是怎么说的,我们会看到.不能修改,编译时常量这些关键性信息. Q:  const为什么不能被修改. A:这个很简单,很多教科书上面都说,当编译器编译时,会将常量的值保存在该程序集的元数据中,下面我们做个实例 看一看. ①:新建一个projectA. 代码如下: // Projec

const & readonly 关键字

1.使用 const 关键字来声明某个常量字段或常量局部变量.常量字段和常量局部变量不是变量并且不能修改. 常量可以为数字.布尔值.字符串或 null 引用(Constants can be numbers, Boolean values, strings, or a null reference). 2.不允许在常数声明中使用 static 修饰符. 3.常数可以参与常数表达式,如下所示: 4.readonly 关键字与 const 关键字不同:const 字段只能在该字段的声明中初始化.re

C#基础知识七之const和readonly关键字

前言 不知道大家对const和readonly关键字两者的区别了解多少,之前真不是很清楚,如果你也不是很清楚的话,那就一起来探讨吧!探讨之前我们先来了解静态变量和动态变量. 静态变量 所谓静态变量就是在编译期间会对变量进行解析,再讲常量的值替换成初始化的值.定义时必须初始化. 动态变量 所谓动态变量就是编译期间会将变量标示只读常量,而不用常量的值代替,定义时可以不初始化,可以延迟到构造函数. const和readonly

C++中关键字的理解--Static

C++中关键字的理解---Static 目录:1.static缘起             2.static自我理解             3.static举例使用             4.总结 -------------------------------------------------------------------------------------------------- 1.static缘起         C语言是面向过程构架,多文件为单位的编码的优异之处在于保持不同

c#中const、static、readonly的区别

1. const与readonly const ,其修饰的字段只能在自身声明时初始化. Readonly 是只读变量,属于运行时变量,可以在类初始化的时候改变它的值.该类型的字段,可以在声明或构造函数中初始化. 因此,根据所使用的构造函数,readonly 字段可能具有不同的值. const只能在初期就使用常量初始化好.对于每一次编译后的结果,const的值是固定的,而readonly的值是可以在运行的时候才确定值的. 2. const 与 static static 定义的是静态变量.可以在外

C++ Primer 学习笔记_25_类与数据抽象(11)--const 用法小结、static与const以及static const(const static)

一.const 用法总结 1.可以对const 的用法做个小总结: const int n = 100;  //定义常量 const Test t(10); const int & ref = n;   //const引用 int& ref = n;  //Error [const与指针] const int* p; //const出现在*前面,表示*p是常量 (*p = 200; //Error) int * const p2;  //const出现在*后面,表示p2是常量 (p2 =

C++(extern关键字的理解和作用深入)

extern关键字的理解和作用深入 extern是一个关键字,它告诉编译器存在着一个变量或者一个函数,如果在当前编译语句的前面中没有找到相应的变量或者函数, 也会在当前文件的后面或者其它文件中定义 引文一.(主要是实战中的各种情况)http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777431.html 1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找

c++中static和inline关键字

一.static变量和static函数 static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别? 答: 1) 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量.全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式. 这两者在存储方式上并无不同.这两者的区别在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的. 而静态全局变量

【黑马程序员】————static和extern关键字1-对函数的作用

一.extern与函数 如果一个程序中有多个源文件(.c),编译成功会生成对应的多个目标文件(.obj),这些目标文件还不能单独运行,因为这些目标文件之间可能会有关联,比如a.obj可能会调用c.obj中定义的一个函数.将这些相关联的目标文件链接在一起后才能生成可执行文件. 先来理解2个概念: 外部函数:如果在当前文件中定义的函数允许其他文件访问.调用,就称为外部函数.C语言规定,不允许有同名的外部函数. 内部函数:如果在当前文件中定义的函数不允许其他文件访问.调用,只能在内部使用,就称为内部函