Readonly和Const的区别

类中的静态常量 关于类中静态常量的声明和定义 class Test { public: static const int const_value = 1; }; static const int const_value = 1为类中的声明式,而非定义式。 定义与声明 定义即为一个声明,它定义有声明引入的实体。除了下述,每个声明都是一个定义: 无函数体的函数声明 int f(int); // declares, but doesn't define f 有 extern 存储类说明符,或语言链接性说明符( 例如 阅读详情


https://www.cnblogs.com/daidaibao/p/4214268.html

目录

什么是静态常量(Const)和动态常量(Readonly)

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

静态常量(Const)和动态常量(Readonly)之间的区别

 

静态常量(Compile-time Constant)

动态常量(Runtime Constant)

定义

声明的同时要设置常量值。

声明的时候可以不需要进行设置常量值,可以在类的构造函数中进行设置。

类型限制

只能修饰基元类型,枚举类型或者字符串类型。

没有限制,可以用它定义任何类型的常量。

对于类对象而言

对于所有类的对象而言,常量的值是一样的。

对于类的不同对象而言,常量的值可以是不一样的。

内存消耗

无。

要分配内存,保存常量实体。

综述

性能要略高,无内存开销,但是限制颇多,不灵活。

灵活,方便,但是性能略低,且有内存开销。

  1. Const修饰的常量在声明的时候必须初始化;Readonly修饰的常量则可以延迟到构造函数初始化 。
  2. Const常量既可以声明在类中也可以在函数体内,但是Static Readonly常量只能声明在类中。Const是静态常量,所以它本身就是Static的,因此不能手动再为Const增加一个Static修饰符。
  3. Const修饰的常量在编译期间就被解析,即:经过编译器编译后,我们都在代码中引用Const变量的地方会用Const变量所对应的实际值来代替; Readonly修饰的常量则延迟到运行的时候。

  举个例子来说明一下:

复制代码
        public static readonly int NumberA = NumberB * 10;
        public static readonly int NumberB = 10;

        public const int NumberC = NumberD*10;
        public const int NumberD = 10;

        static void Main(string[] args)
        {
            Console.WriteLine("NumberA is {0}, NumberB is {1}.", NumberA, NumberB);//NumberA is 0, NumberB is 10.
            Console.WriteLine("NumberC is {0}, NumberD is {1}.", NumberC, NumberD);//NumberC is 100, NumberD is 10.
            Console.ReadKey();
        }
复制代码
View Code

  以上是语法方面的应用,那在实际的用法上,还是有些微妙的变化,通常不易发觉.
  举个例子来说明一下:
  在程序集DoTestConst.dll 中有一个类MyClass,定义了一个公开的静态变量Count

    public static class MyClass
    {
        public const int Count = 10;
    }

  然后另外一个应用程序中引用DoTestConst.dll,并在代码中作如下调用:

    public static void Main(string[] args)
    {
        Console.WriteLine(DoTestConst.MyClass.Count);//输出10
        Console.ReadKey();
    }

  毫无疑问,非常简单的代码,直接输出10。
  接下来更新MyClass的Count的值为20,然后重新编译DoTestConst.dll,并更新到应用程序的所在目录中,注意不要编译应用程序。那么这时候的输出结果按预期那么想应该是20才对,但实际上还是10,为什么呢?
  这就是Const的特别之处,有多特别还是直接看生成的IL,查看IL代码(假设这时候Count的值为10)

  IL_0000: nop
  IL_0001: ldc.i4.s 10
  IL_0003: call void [mscorlib]System.Console::WriteLine(int32)

  红色代码很明显的表明了,直接加载10,没有通过任何类型的加载然后得到对应变量的,也就是说在运行时没有去加载DoTestConst.dll,那么是否意味着没有DoTestConst.dll也可以运行呢?答案是肯定的,删除DoTestConst.dll也可以运行,是否很诡异呢?也就解释了之前的实验,为什么更新Const变量的值之后没有调用新的值,因为程序在运行的时候根本不会去加载DoTestConst.dll。那么10这个值是从哪来的呢?实际上CLR对于Const变量做了特殊处理,是将Const的值直接嵌入在生成的IL代码中,在执行的时候不会再去从dll加载。这也带来了一个不容易发觉的Bug,因此在引用其他程序集的Const变量时,需考虑到版本更新问题,要解决这个问题就是把调用的应用程序再编译一次就ok了。但实际程序部署更新时可能只更新个别文件,这时候就必须用Readonly关键字来解决这个问题。

  接下来看Readonly的版本:

    public static class MyClass
    {
        public static readonly int Count = 10;
    }

  调用方代码不变,接着看生成的IL代码:

  IL_0000: nop
  IL_0001: ldsfld int32 [DoTestConst]DoTestConst.MyClass::Count
  IL_0006: call void [mscorlib]System.Console::WriteLine(int32)

  很明显加载代码变了,一个很常见的ldsfld动作,请求了DoTestConst.MyClass的Count变量,是通过强制要求加载DoTestConst来实现的。因此这时候更新Count的值重新编译之后,还是不编译调用程序,然后再执行就会看到新的值。而这时候如果删除DoTestConst.dll那么,会出现找不到dll之类的异常。这也充分说明了对于Readonly定义的变量是在运行时加载的。

动态常量(Readonly)被赋值后不可以改变

  ReadOnly 变量是运行时变量,它在运行时第一次赋值后将不可以改变。其中“不可以改变”分为两层意思:

  1. 对于值类型变量,值本身不可以改变(Readonly, 只读)
  2. 对于引用类型变量,引用本身(相当于指针)不可改变。

  值类型变量,举个例子说明一下:

复制代码
    public class Student
    {
        public readonly int Age;

        public Student(int age)
        {
            this.Age = age;
        }
    }
复制代码

  Student的实例Age在构造函数中被赋值以后就不可以改变,下面的代码不会编译通过:

Student student = new Student(20);
student.Age = 21; //错误信息:无法对只读的字段赋值(构造函数或变量初始化器中除外)

  引用类型变量,举个例子说明一下:

复制代码
    public class Student
    {
        public int Age; //注意这里的Age是没有readonly修饰符的

        public Student(int age)
        {
            this.Age = age;
        }
    }

    public class School
    {
        public readonly Student Student;

        public School(Student student)
        {
            this.Student = student;
        }
    }
复制代码

  School实例的Student是一个引用类型的变量,赋值后,变量不能再指向其他任何的Student实例,所以,下面的代码将不会编译通过:

School school = new School(new Student(10));
school.Student = new Student(20);//错误信息:无法对只读的字段赋值(构造函数或变量初始化器中除外)

  引用本身不可以改变,但是引用说指向的实例的值是可以改变的。所以下面的代码是可以编译通过的:

School school = new School(new Student(10));
school.Student.Age = 20;

  在构造方法中,我们可以多次对Readonly修饰的常量赋值。举个例子说明一下:

复制代码
    public class Student
    {
        public readonly int Age = 20;//注意:初始化器实际上是构造方法的一部分,它其实是一个语法糖

        public Student(int age)
        {
            this.Age = age;
            this.Age = 25;
            this.Age = 30;
        }
    }
复制代码

总结

  Const和Readonly的最大区别(除语法外)
  Const的变量是嵌入在IL代码中,编译时就加载好,不依赖外部dll(这也是为什么不能在构造方法中赋值)。Const在程序集更新时容易产生版本不一致的情况。
Readonly的变量是在运行时加载,需请求加载dll,每次都获取最新的值。Readonly赋值引用类型以后,引用本身不可以改变,但是引用所指向的实例的值是可以改变的。在构造方法中,我们可以多次对Readonly赋值。

C#基础-定义常量的两种方法 阅读详情

相关推荐

ACS驱动器直线电机回零程序与误差补偿Buffer实战解析

本文深入解析了ACS驱动器控制直线电机时,实现高精度回零与误差补偿的完整实战流程。核心在于利用驱动器的D-Buffer功能,将激光干涉仪测量的误差数据导入补偿数组,通过ERRORMAP1D指令进行映射,从而实时修正定位误差,显著提升设备重复定位精度。文章详细拆解了回零程序逻辑、补偿参数设置及关键调试避坑指南。

648

变量、常量、静态变量、静态常量

静态变量、成员变量、常量

u014365523的博客 5161

Windows10 Qt下用MINGW 编译VTK-8.1.0

1. 材料准备(1) 下载VTK-8.1.0: https://www.vtk.org/download/(2) 下载TIFF库: http://gnuwin32.sourceforge.net/packages/tiff.htm(直接安装即可,注意选择路径不包含中文字符)2. 安装: (1) cmake配置: a. Module下配置:勾选下图所示的六项 b. Build 配置:勾选这里能够在b...

hit1524468的专栏 3891

unity的C#学习——静态常量和动态常量的定义与使用

在C#中,常量是一种不可改变的量,一旦被定义,其值就不能被修改。C#中有两种类型的常量,静态常量和动态常量。

时生的博客 2286

别再手动抄表了!用MCGS触摸屏自动存数据到U盘,5分钟搞定报表导出

本文详细介绍了如何利用MCGS触摸屏实现工业数据自动记录与U盘导出,彻底告别传统手动抄表方式。通过昆仑通态MCGS系统,可构建零误差自动化报表系统,实现实时数据采集、双重备份及标准CSV格式导出,大幅提升数据准确性和工作效率。

weixin_30872157的博客 793

从部署到养成:Hermes智能体接入DeepSeek与微信机器人的完整实战指南

智能体(Agent)正成为大模型从“对话”走向“行动”的关键形态。它通过拆解指令、调用工具、执行任务,让AI真正参与工作流。Hermes作为可本地部署的开源智能体框架,支持接入DeepSeek等主流大模型,并提供网关、工具调用、记忆管理等模块化能力。从Docker容器部署到微信机器人桥接,从自动化定时任务到Computer Use桌面控制,Hermes将个人助理从概念落地为可运行的工程系统。本文基于真实实践,梳理架构原理、部署流程、API配置与高频故障排查,为技术玩家提供一套从零到一的上手指南。

weixin_29045001的博客 263

【C++】类中静态(static)成员变量、静态(static)成员函数和静态常量(static const)的应用

本文介绍了C++中静态成员变量、静态常量和静态成员函数的特性、应用、常见的软件设计模式以及单例模式、工厂模式的实现。静态成员变量、静态常量和静态成员函数可以帮助我们更好地组织数据和操作,并提高代码的效率和可读性。

crr411422的博客 1万+

解决vscode 连接服务器报错:The remote host may not meet VS Code Server‘s prerequisites for glibc and libstdc++

解决vscode远程连接服务器报错:The remote host may not meet VS Code Server's prerequisites for glibc and libstdc++ (The remote host does not meet the prerequisites for running VS Code Server)

qq_37200100的博客 9910

readonly和const的区别

部分开发者会认为,readonly修饰的变量是不能修改的,在以后的开发中从不对ReadOnly的变量进行修改,形成思维定势,这个观念是错误的。 首先要明确一点:更改!=重新分配(赋值) 对于简单类型(如int),更改是等于重新赋值,因为默认操作符只有=, 但于对于复杂类型,就不一定了。 例如:对于集合类型,可以增加、移除、清空内容。 例子如下: public interface IA { } pu...

陈云佳的专栏 4523

【UV打印机】PrintExp打印软件教程(四)-设置校准电压

序号名称功能说明1校准材料设置定义当前打印材料,不同的材料参数绑定不同的校准值2向导勾选进行校准向导操作3校准类型包括喷头安装、步进校准、喷头间距、套色校准、双向校准4类型子项同类型子项5操作步骤校准存在步骤和校准说明示意图。

Print World的专栏 5074

LoRa模块选型指南:正点原子ATK-LORA-01与SX1278芯片深度评测(含实测距离/功耗数据)

本文深度评测了正点原子ATK-LORA-01与SX1278芯片的性能表现,通过实测数据展示其在复杂环境中的通信距离与功耗表现。特别适合智慧农业、工业监测等物联网应用场景,提供详细的配置指南和优化技巧,帮助开发者实现高效、低功耗的LoRa通信解决方案。

weixin_29191081的博客 290

const和readonly的区别

const和readonly的区别 const是静态常量,const是编译时常量;readonly是动态常量,是运行时常量,const较高效,readonly较灵活。 1.const默认是静态的,只能由类型来访问,不能与static同时使用;readonly默认是非静态的,由实例对象来访问,可以显示使用static定义为静态成员; 2.const只能应用在值类型和string类型上,其他引用类型常量只能定义为null,否则以new为const引用类型常量赋值,;readonly只读字段,可以使任意类型,但是

PangPangPig123的博客 4114

【CAN总线测试】——通讯相关诊断测试

本章主要介绍通讯相关诊断测试用例设计

LOVE135149的博客 1815

Const 和 static readonly的区别

static readonly需要注意的一个问题是,对于一个static readonly的Reference类型,只是被限定不能进行赋值(写)操作而已。而对其成员的读写仍然是不受限制的。 public static readonly MyClass myins = new MyClass(); … myins.SomeProperty = 10; //正常 myins = new MyClas...

一杯敬明天 1340

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

const 和 readonly 的区别

const和readonly的区别,总是不太清楚,于是查了查资料。 const和readonly的区别,总是不太清楚,于是查了查资料。 const的概念就是一个包含不能修改的值的变量。常数表达式是在编译时可被完全计算的表达式。因此不能从一个变量中提取的值来初始化常量。如果const int a = b+1;b是一个变量,显然不能再编译时就计算出结果...

weixin_34184158的博客 273

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Const和ReadOnly的区别

1.       const和readonly都是用来表示常量的。2.       初始化赋值不同a)         Const必须在声明的时候即赋值。b)         Readonly可以在初始化的过程中赋值。在其他地方赋值,编译器会报错。因此,根据所使用的构造函数,readonly字段可以具有不同的值。3.       Const是编译时常数,而readonly字段可用于

Eric_insh的专栏 813

鸿蒙中 const 和 readonly区别

鸿蒙开发中const与readonly的区别:const用于编译时常量,必须在声明时初始化,类型自动推断为字面量;readonly用于运行时常量,可在构造函数初始化,保留原始类型。const限制变量引用但对象属性可变,readonly完全禁止修改。建议:简单值用const,对象属性用readonly,深度不变性可结合Readonly<T>。常见误区包括误认const能冻结对象和在非构造函数中修改readonly属性。

梦想不只是梦与想的博客 707

Const和readonly的区别

const和readonly的值一旦初始化不再刻意改变const只能在声明是初始化,readonly既可以在声明时初始化也可以在构造器中初始化; const隐含static不可再写static const; readonly则不默认static如需要可以写static readonly const即开以用来修饰类中的成员,也可以修饰函数体内的局部变量; readonly之可以用于修饰类中的成员; ...

BaWangLi的博客 453

.NET中,const和readonly区别

在.NET中,const和readonly都用于定义不可变的值,但它们在行为和使用场景上有显著区别。◦ 若修改const值,引用它的其他程序集必须重新编译,否则继续使用旧值(硬编码到IL中)。◦ 修改后,依赖程序集无需重新编译即可获取新值(运行时解析)。◦ 值被编译到IL中,不占用实际内存空间(类似于字面量)。◦ 作为字段存储在内存中,每个实例或类有独立存储。◦ 运行时常量,可以在声明时或构造函数中赋值。◦ 默认为实例级别,每个对象可拥有不同的值。◦ 需运行时计算的配置值或对象。◦ 易引发版本不一致问题。

chenglin016的博客 1091

C#中const、static、readonly的区别

一、 const与readonly ①【const】其修饰的字段只能在自身声明时初始化。 ②【Readonly】是只读变量,属于运行时变量,可以在类初始化的时候改变它的值。该类型的字段,可以在声明或构造函数中初始化。 ③小结: 《1》根据所使用的构造函数,readonly 字段可能具有不同的值。 《2》对于每一次编译后的结果,const的值是固定的,而readonly的值是可以在运行的时...

提供C#相关开发 、云计算、运维测试、网络安全相关技术分享与服务,有意向可联系。 3305
上一篇: 程序调试技巧 —— Attach to Process
下一篇: WebService-example
hongyanjava
博客等级 码龄17年 12粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值