当前位置: 首页 > article >正文

C# 中 readonly 与 const 的使用

总目录


前言

在C#编程中,readonly 和 const 是两个用于定义不可变数据的关键字。它们都旨在创建那些一旦赋值后就不能再改变的字段或变量。尽管这两个关键字看起来相似,但它们有着不同的特性和适用场景。本文将深入探讨 readonly 和 const 的区别,并介绍如何根据具体需求选择合适的选项


一、const 关键字

1. 基本概念

const 用来声明编译时常量,即其值是在编译时确定并在程序运行期间不会改变的。这意味着 const 字段的值必须在声明时就赋予,并且该值在整个应用程序生命周期内都是固定的。

2. 语法示例

public class ConstantsExample
{
    // 定义类级别的常量
    public const double Pi = 3.14159265358979323846; 
    public const string AppName = "MyApplication";

    public void DisplayConstants()
    {
        // 定义局部常量
        const int MaxItems = 100; 
        // 使用常量
        Console.WriteLine($"Pi: {Pi}, App Name: {AppName}, Max Items: {MaxItems}");
    }
}
internal class Program
{
        
    static void Main(string[] args)
    {
         // 使用常量
         Console.WriteLine($"Pi: {ConstantsExample.Pi}, App Name: {ConstantsExample.AppName}");
    }
}

3. 特性

  • 必须初始化:在声明 const 常量时,必须同时为其赋值,否则会引发编译错误。
	public const string ConstStr;//报错:CS0145:常量字段要求提供一个值
  • 编译时求值:const 常量的值在编译时就被确定并替换到使用它的地方。这意味着,如果const常量的值发生变化,所有引用它的代码都需要重新编译。
    • 如果在一个程序集中定义了 const,并在另一个程序集中使用它,当 const 的值发生变化时,必须重新编译所有依赖它的程序集,这是一个很隐蔽的问题。而 readonly 通常没有这个问题。
    • const 效率高的原因是代码中引用 const 变量的地方,经过编译器编译后会直接使用 const 变量的实际值来代替,如:
		const int constVal = 100;
		Console.WriteLine(constVal);
		编译后的 IL 代码实际上是:
		Console.WriteLine(100);
  • 数据类型限制:const 常量只能是以下类型:sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double、decimal、bool、string,或者是枚举类型。
  • 作用域:const 可以作为类成员、结构体成员或者局部变量(从C# 7.2开始),但不能作为实例成员。

二、readonly 关键字

1. 基本概念

readonly 也用来定义只读字段,其值可以在声明时或构造函数中初始化,初始化后便不能再更改。与const不同,readonly字段的值在运行时确定,这为我们提供了更大的灵活性。。

2. 语法示例

可以在声明时或构造函数中初始化

public class ReadonlyExample
{
    // 声明只读字段
    public readonly double CurrentVersion; 
    public readonly string CompanyName;

    public ReadonlyExample(double version, string company)
    {
        // 在构造函数中初始化
        CurrentVersion = version;
        CompanyName = company;
    }
}

3. 特性

  • 初始化时机:readonly字段可以在声明时初始化,也可以在构造函数中初始化,但是只能初始化一次。这为对象的初始化提供了更多的灵活性。
  • 运行时求值:readonly字段的值可以在运行时确定,这使得我们可以根据不同的运行时条件来初始化它。例如,从配置文件、数据库或其他外部源获取值。
    • readonly 字段在运行时分配内存并进行访问,与普通字段类似。
  • 数据类型限制:readonly字段可以是任何数据类型
  • 作用域:readonly 可以作为静态成员或实例成员存在,提供更大的灵活性。

三、readonly 与 const 的区别

1. 初始化时间

  • const 在编译时初始化,其值在编译期间就必须确定。
  • readonly 可以在运行时初始化,既可以在声明时赋值,也可以在构造函数中赋值。

2. 内存分配

  • const 常量在编译时会将其值嵌入到使用它的代码中,不会单独分配内存。
  • readonly 字段在运行时为每个对象实例分配内存,即使多个对象实例的readonly字段值相同。
  • const 天然就是静态的,不能为 const 常量添加 static 修饰符。readonly 则不然。

3. 数据类型限制

  • const 只支持有限的数据类型,如基本数值类型、布尔类型、字符串类型和枚举类型。
  • readonly 没有数据类型限制,可以用于任何数据类型。

4. 可变性

  • const 的值在编译后就完全固定,无法在运行时更改。
  • readonly 的值虽然不能在初始化后更改,但可以根据运行时的不同情况进行初始化。

四、适用场景

  • 编译时已知值:如果您知道一个值在编译时就已经确定,并且永远不会改变,那么应该使用 const。数学常量与固定配置:如圆周率Pi、重力加速度G等数学常量,以及应用程序的固定配置参数,如数据库连接字符串的一部分(如果从不改变)。
  • 运行时确定值:如果值需要在运行时计算或依赖于其他因素(如配置文件、用户输入),则应使用 readonly。此外,当您希望某个字段在对象创建后保持不变,但其值可能因不同对象而异时,readonly 是更好的选择。
  • 性能考虑:由于 const 值会被直接嵌入到调用方的代码中,因此对于频繁使用的常量,它可能会导致更大的程序集大小。另一方面,readonly 字段会在运行时加载,这通常会更节省空间,但在第一次访问时会有轻微的性能开销。
  • 可维护性:使用 const 有助于提高代码的可读性和自我描述能力,因为读者可以立即看到常量的值。然而,如果将来需要更改这个值,那么所有引用了该常量的地方都需要重新编译。相比之下,readonly 更易于维护,特别是在大型项目中。

结语

回到目录页:C#/.NET 知识汇总
希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。


参考资料:
使用 C# readonly 和 const 定义常量,高手不愿意告诉你的 10 个真相


http://www.kler.cn/a/513550.html

相关文章:

  • 基于STM32的智能门锁安防系统(开源)
  • Tcl教程
  • Git处理冲突详解
  • 迈向 “全能管家” 之路:机器人距离终极蜕变还需几步?
  • RabbitMQ实现延迟消息发送——实战篇
  • Spring Boot项目集成Redisson 原始依赖与 Spring Boot Starter 的流程
  • mapbox js本地化部署
  • Python Web开发:使用FastAPI构建视频流媒体平台
  • 嵌入式产品级-超小尺寸热成像相机(从0到1 硬件-软件-外壳)
  • 【C++】开源:libpcap网络数据捕获库安装与应用
  • 【python】实现图像中的阴影去除 | 方案和代码
  • Nginx HTTP 服务器基础配置
  • 2090. 半径为 k 的子数组平均值
  • 【深度学习基础】多层感知机 | 多层感知机概述
  • Android开发,待办事项提醒App的设计与实现(个人中心页)
  • httpx上传文件/IO流缓慢的问题分析及解决
  • SQL-leetcode—1141. 查询近30天活跃用户数
  • 在亚马逊云科技上用AI提示词优化功能写出漂亮提示词(下)
  • css动画水球图
  • 【数学建模美赛速成系列】O奖论文绘图复现代码
  • VM模块开发 C++ 工程配置
  • “大模型横扫千军”背后的大数据挖掘--浅谈MapReduce
  • Spring Boot + Netty + WebSocket 实现消息推送
  • 深挖——final
  • 分布式搜索引擎02
  • Emacs折腾日记(十一)——求值规则