总结一下const和readonly
- const和readonly的值一旦初始化则都不再可以改写;
- const只能在声明时初始化;readonly既可以在声明时初始化也可以在构造器中初始化;
- const隐含static,不可以再写static const;readonly则不默认static,如需要可以写static readonly;
- const是编译期静态解析的常量(因此其表达式必须在编译时就可以求值);readonly则是运行期动态解析的常量;
- const既可用来修饰类中的成员,也可修饰函数体内的局部变量;readonly只可以用于修饰类中的成员
前面是我从网上摘录的,文字太多,懒得自己再总结和打字了.
注意,第四点尤为重要,我用以下代码来说明和验证:
1.建立文本文件,然后改成.cs文件-lib.cs:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace ConstReadonly_Base
- {
- public class Test
- {
- public const double PI = 3.14;
- public static readonly double pi = 3.14;
- }
- }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConstReadonly_Base
{
public class Test
{
public const double PI = 3.14;
public static readonly double pi = 3.14;
}
}
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace ConstReadonly_Demo
- {
- class Program
- {
- static void Main(string[] args)
- {
- Console.WriteLine(ConstReadonly_Base.Test.PI);
- Console.WriteLine(ConstReadonly_Base.Test.pi);
- Console.ReadKey();
- }
- }
- }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConstReadonly_Demo
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(ConstReadonly_Base.Test.PI);
Console.WriteLine(ConstReadonly_Base.Test.pi);
Console.ReadKey();
}
}
}
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace ConstReadonly_Base
- {
- public class Test
- {
- public const double PI = 3.1415;
- public static readonly double pi = 3.1415;
- }
- }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConstReadonly_Base
{
public class Test
{
public const double PI = 3.1415;
public static readonly double pi = 3.1415;
}
}
- .field public static literal float64 PI = float64(3.1415000000000002)
.field public static literal float64 PI = float64(3.1415000000000002)
- .field public static initonly float64 pi
.field public static initonly float64 pi
明显lib.cs被编译成元数据和IL汇编时,PI直接被替换成float64(3.1415000000000002)
而.cctor: void()静态构造函数中,
- .method private hidebysig specialname rtspecialname static
- void .cctor() cil managed
- {
- // Code size 15 (0xf)
- .maxstack 8
- IL_0000: ldc.r8 3.1415000000000002
- IL_0009: stsfld float64 ConstReadonly_Base.Test::pi
- IL_000e: ret
- } // end of method Test::.cctor
.method private hidebysig specialname rtspecialname static
void .cctor() cil managed
{
// Code size 15 (0xf)
.maxstack 8
IL_0000: ldc.r8 3.1415000000000002
IL_0009: stsfld float64 ConstReadonly_Base.Test::pi
IL_000e: ret
} // end of method Test::.cctor
pi是动态分配内存的,直到运行时才调用静态构造函数来初始化pi.
如果这时你还是不太明白,让我们接下去看:
用ILDasm工具,选择demo.exe,内容如下:
我们来看看Main函数中我们到底做了些什么:
- .method private hidebysig static void Main(string[] args) cil managed
- {
- .entrypoint
- // Code size 34 (0x22)
- .maxstack 8
- IL_0000: nop
- IL_0001: ldc.r8 3.1400000000000001
- IL_000a: call void [mscorlib]System.Console::WriteLine(float64)
- IL_000f: nop
- IL_0010: ldsfld float64 ['ConstReadonly-Base']ConstReadonly_Base.Test::pi
- IL_0015: call void [mscorlib]System.Console::WriteLine(float64)
- IL_001a: nop
- IL_001b: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
- IL_0020: pop
- IL_0021: ret
- } // end of method Program::Main
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 34 (0x22)
.maxstack 8
IL_0000: nop
IL_0001: ldc.r8 3.1400000000000001
IL_000a: call void [mscorlib]System.Console::WriteLine(float64)
IL_000f: nop
IL_0010: ldsfld float64 ['ConstReadonly-Base']ConstReadonly_Base.Test::pi
IL_0015: call void [mscorlib]System.Console::WriteLine(float64)
IL_001a: nop
IL_001b: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
IL_0020: pop
IL_0021: ret
} // end of method Program::Main
WriteLine()打印PI时,
- IL_0001: ldc.r8 3.1400000000000001
- IL_000a: call void [mscorlib]System.Console::WriteLine(float64)
IL_0001: ldc.r8 3.1400000000000001
IL_000a: call void [mscorlib]System.Console::WriteLine(float64)
这说明编译时,PI被编译成一个常量.
WriteLine()打印pi时,
- IL_0010: ldsfld float64 ['ConstReadonly-Base']ConstReadonly_Base.Test::pi
IL_0010: ldsfld float64 ['ConstReadonly-Base']ConstReadonly_Base.Test::pi
这说明编译时,pi被编译成调用ConstReadonly_Base.Test::pi,可见pi量是动态分配和调用的.
最新文章
- CSS3盒模型display:box;box-flex:3;
- Here String 中不该进行分词
- 如何通过JQuery将DIV的滚动条滚动到指定的位置
- MAHOUT_LOCAL is not set; adding HADOOP_CONF_DIR to classpath.
- 电脑不能浏览网页but能登录qq,解决方案总结
- HTML 几种特别分割线特效
- linux 多线程基础3
- Git for Windows 工具下载及配置
- Asp.NET开启一个线程,不停的执行
- 【问题解决记录】Error: Cannot find module '@ionic/app-scripts'
- git和github新手安装使用教程(三步入门)
- SpringCloud学习笔记(7)——Sleuth
- 通过java把excel内容上传到mysql
- Maven安装教程详解
- 解决js复制在安卓和ios兼容问题
- wx 参数传值
- Entity framework中LINQ的使用
- sql server导入excel数据
- node模块加载机制。
- linux常用命令:head 命令