深入理解C#中的readonly与const:区别与应用场景

目录

引言

readonly与const的基本定义

readonly与const的主要区别

readonly与const的使用场景

示例与解析

结论


引言

 const 关键字 - C# reference | Microsoft Learn

只读关键字 - C# reference | Microsoft Learn

        在C#编程中,readonlyconst都是用于声明不可变变量的关键字。然而,它们之间存在一些关键的区别,这些区别决定了它们在不同场景下的适用性。本文将深入探讨readonlyconst的区别,并通过实际示例来说明它们各自的使用场景。

readonly与const的基本定义

  • readonly:用于声明只读字段。这些字段可以在声明时或在构造函数中赋值,但在对象实例化之后,其值就不能再被修改。
  • const:用于声明编译时常量。这些常量的值必须在声明时确定,并且必须是编译时常量表达式。一旦声明,其值就不能再被修改。

readonly与const的主要区别

  1. 赋值时机const必须在声明时赋值,而readonly可以在声明时或构造函数中赋值。
  2. 类型限制const只能用于基本数据类型、枚举类型或字符串类型的字面量;而readonly可以用于任何类型。
  3. 运行时与编译时const的值在编译时确定,而readonly的值在运行时确定。
  4. 静态构造函数readonly静态字段可以在静态构造函数中初始化,而const则不能。
  5. 内存使用const不占用运行时内存(除了字符串字面量),而readonly会占用。

readonly与const的使用场景

  • const:适用于需要在编译时确定其值,并且不会改变的常量,如数学常量、物理常量等。
  • readonly:适用于需要在运行时或基于某些条件确定其值的只读字段,如配置数据、只读属性等。此外,由于readonly可以应用于任何类型,因此它也常用于引用类型的只读字段。

示例与解析

1. const 示例

// 定义一个const常量,用于存储圆周率π的值  
public const double Pi = 3.14159265358979323846;  
  
class Program  
{  
    static void Main()  
    {  
        // 直接使用const常量  
        Console.WriteLine("Pi的值是: " + Pi);  
  
        // 尝试修改const常量的值(这将导致编译错误)  
        // Pi = 3.0; // 编译错误:无法修改const字段  
    }  
}  
  
// 解析:  
// 在这个例子中,我们定义了一个名为Pi的const常量,用于存储圆周率的值。由于const常量必须在声明时赋值,并且其值在编译时就已经确定,因此我们不能在后续代码中修改它的值。这保证了Pi的值在整个程序中都是不变的。

 2. readonly 示例(实例字段)

public class Person  
{  
    // 定义一个readonly实例字段,用于存储人的名字  
    public readonly string Name;  
  
    // 构造函数中初始化readonly字段  
    public Person(string name)  
    {  
        Name = name;  
    }  
  
    // 尝试在方法内部修改readonly字段(这将导致编译错误)  
    // public void ChangeName(string newName)  
    // {  
    //     Name = newName; // 编译错误:无法修改readonly字段  
    // }  
}  
  
class Program  
{  
    static void Main()  
    {  
        Person alice = new Person("Alice");  
        Console.WriteLine("Alice的名字是: " + alice.Name);  
  
        // 尝试直接修改alice的Name属性(这是不可能的,因为Name是readonly的)  
        // alice.Name = "Bob"; // 编译错误:无法修改通过只读属性访问的字段  
    }  
}  
  
// 解析:  
// 在这个例子中,我们定义了一个名为Person的类,并在其中声明了一个readonly实例字段Name。由于Name是readonly的,我们只能在声明时或在构造函数中为其赋值。在Person类的其他方法中(如ChangeName方法,尽管这里被注释掉了),我们不能修改Name的值。同样,在Program类的Main方法中,我们也不能直接修改alice对象的Name属性。

3. readonly 示例(静态字段)

public class Config  
{  
    // 定义一个readonly静态字段,用于存储配置数据  
    public static readonly string DatabaseConnectionString = "Server=localhost;Database=MyDatabase;";  
  
    // 静态构造函数(可选,但可用于复杂的初始化逻辑)  
    static Config()  
    {  
        // 这里可以执行一些初始化代码,但通常readonly静态字段直接在声明时赋值  
    }  
}  
  
class Program  
{  
    static void Main()  
    {  
        Console.WriteLine("数据库连接字符串是: " + Config.DatabaseConnectionString);  
  
        // 尝试修改readonly静态字段(这将导致编译错误)  
        // Config.DatabaseConnectionString = "新的连接字符串"; // 编译错误:无法修改通过只读静态属性访问的字段  
    }  
}  
  
// 解析:  
// 在这个例子中,我们定义了一个名为Config的类,并在其中声明了一个readonly静态字段DatabaseConnectionString,用于存储数据库连接字符串。由于DatabaseConnectionString是readonly的且是静态的,我们只能在声明时或在静态构造函数中为其赋值。在Program类的Main方法中,我们不能修改Config类的DatabaseConnectionString字段的值。这种机制在存储只读配置数据时非常有用。

结论

readonlyconst都是C#中用于声明不可变变量的关键字,但它们之间存在一些关键的区别。了解这些区别并正确使用它们,可以帮助我们编写更高效、更安全的代码。在实际开发中,我们应根据具体需求选择使用readonly还是const

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/742513.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【azure openaiai翻译】翻译功能测试及对比(定价,响应速度,响应限制,翻译质量)

最近在测试翻译质量,用到了azure ai service里的文本翻译(简称ai翻译)和azure openai 。 告一段落,辅以笔记。这两种将分别从定价,响应速度,响应限制,翻译质量进行讲解。 1.azure openai 对于内…

EthernetIP IO从站设备数据 转opc ua项目案例

1 案例说明 设置网关采集EthernetIP IO设备数据把采集的数据转成opc ua协议转发给其他系统。 2 VFBOX网关工作原理 VFBOX网关是协议转换网关,是把一种协议转换成另外一种协议。网关可以采集西门子,欧姆龙,三菱,AB PLC&#xff0…

2005年下半年软件设计师【上午题】试题及答案

文章目录 2005年下半年软件设计师上午题--试题2005年下半年软件设计师上午题--答案 2005年下半年软件设计师上午题–试题 2005年下半年软件设计师上午题–答案

ModbusRTU协议报文解析

ModbusRTU协议报文解析 报文格式: 设备地址/从站地址: 1个字节 指定目标设备地址(从站地址) 功能码:1个字节 功能码在modbus协议用于表示信息帧的功能,例如读取线圈状态、读取寄存器等。 数据&#xff…

C语言数据结构-分析期末选择题考点(一)

昔我往矣,杨柳依依 今我来思,雨雪霏霏 契子✨ 有道是:得选择题者得天下。临近考试,便总结一下数据结构选择题的常考题型吧,以及预测一下考点,一来是为了备考,二来可以水文。祝各位老铁 “挂柯南…

韩顺平0基础学java——第30天

p600-611 坦克大战! 艰难推进中 坦克大战-子弹 发射子弹 1.当发射一颗子弹后,就相当于启动一个线程 2.玩家拥有子弹对象,当按下J时,就启动发射行为(线程),让子弹不停移动,形成…

(上位机APP开发)调用华为云命令API接口给设备下发命令

一、功能说明 通过调用华为云IOT提供的命令下发API接口,实现下面界面上相同的功能。调用API接口给设备下发命令。 二、JavaScript代码 function sendUnlockCommand() {var requestUrl = "https://9bcf4cfd30.st1.iotda-app.cn-north-4.myhuaweicloud.com:443/v5/iot/60…

全国首场以AI数字内容风控为主题的大会正式官宣,首批演讲嘉宾和议题揭晓!

曾经我们感叹的“AI迎来了iPhone时刻”,如今已变成“iPhone迎来了AI时刻”。前段时间,苹果全球开发者大会的召开,以及闻声而起的资本市场,无一不再次佐证了AI的无穷想象。 从OpenAI直播演示GPT-4o和谷歌的I/O开发者大会2024&…

空调制冷剂泄漏引发健康隐患,冷媒传感器实时监测至关重要

随着夏季的脚步逐渐临近,气温逐渐攀升,空调成为了许多家庭和企业必不可少的降温设备。然而,近年来多起因空调制冷剂泄漏导致的健康问题和安全事故,让人们开始重新审视空调使用安全的重要性。其中,冷媒传感器的实时监测…

智能AI在线人工智能对话源码系统 完整的代安装码+搭建部署教程

系统概述 智能 AI 在线人工智能对话源码系统是一款前沿的技术解决方案,它融合了人工智能的强大能力,为用户提供了一个高效、智能的对话平台。该系统基于先进的算法和模型,能够理解用户的输入,并以高度准确和自然的方式进行回应。…

深度测试中的隐藏面消除技术

by STANCH 标签:#计算机图形学 #深度测试 #深度测试 #隐藏面消除 1.概述 根据我们的日常经验,近处的物体会挡住后面的物体,在三维场景中通常通过深度缓冲来实现这样的效果。深度缓冲记录着屏幕对应的每个像素的深度值。模型一开始所在的局部…

计算机工具软件安装攻略:Chrome浏览器下载安装及使用

1 Chrome简介 Chrome是谷歌公司开发的一款免费网页浏览器它快速、稳定、安全拥有简洁流畅的界面和丰富的应用程序内置了强大的谷歌搜索引擎。Chrome使用Blink浏览器引擎和V8 JavaScript引擎支持多种插件和扩展程序让浏览网页更便捷。它可以与Android手机良好同步支持跨设备浏览…

AI降重技术:论文查重率的智能解决方案

现在大部分学校已经进入到论文查重降重的阶段了。如果查重率居高不下,延毕的威胁可能就在眼前。对于即将告别校园的学子们,这无疑是个噩梦。四年磨一剑,谁也不想在最后关头功亏一篑。 查重率过高,无非以下两种原因。要么是作为“…

中霖教育怎么样?中霖教育好吗?

中霖教育怎么样?中霖教育好吗? 中霖教育包括师资力量、课程设置、教学方法等都是经过不断完善来制定的,我们拥有专业且经验丰富的师资队伍,在教学过程中更注重个性化教学方式,针对每个学员的需求和学习情况制定专属的学习计划。 无论是在…

养殖自动化管理系统:开启智慧养殖新篇章

在现代农业的快速演进中,养殖业正经历一场前所未有的技术革命。养殖自动化管理系统,作为这场变革的前沿科技,正逐步成为推动行业高效、环保、可持续发展的关键力量。本文将深入探讨自动化养殖系统如何通过精准管理、智能监控、数据驱动决策&a…

无线领夹麦克风哪个牌子好,一篇教你无线领夹麦克风怎么挑选!

对于领夹麦克风这一术语,可能在非专业人士听来颇为生僻,然而在互联网行业工作者和短视频博主中,它却是一个常见的必备工具。如果你正计划成为一名短视频创作者,或者即将涉足视频拍摄与直播等互动媒体活动,那么熟悉并掌…

【数学建模】—【Python库】—【Numpy】—【学习】

目录 ​编辑 1. NumPy安装 2. ndarray对象 1. 创建ndarray 1.从列表或元组创建: 2.使用内置函数创建: 2. ndarray属性 3. 数组运算 1. 基本运算 2. 数学函数 3.统计函数 4. 数组索引与切片 1. 一维数组索引与切片 2.多维数组索引与切片 5.…

基于单片机的转速测量系统设计

【 摘 要 】 伴 随 着 我 国 科 学 技 术 水 平 的 快 速 发 展 , 当 前 我 国 对 单 片 机 的 转 速 测 量 系 统 控 制 这 一 领 域 也 越 来 越 趋 于 智 能 化 。 本 文 主 要 以 单 片 机 平 台 为 主 要 的 出 发 点 , 对 电 机 进 行 转 …

迁移学习——CycleGAN——循环一致性对抗网络

CycleGAN 1.导入需要的包2.数据加载(1)to_img 函数(2)数据加载(3)图像转换 3.随机读取图像进行预处理(1)函数参数(2)数据路径(3)读取文…

Springboot 前端传参后台接收当不存在参数bean对象时报错解决

后端接收代码 PostMapping(value "/updateUser") public String updateUser(RequestBody SysUser sysUser) {} 当前端传送多于的参数时报错如下: Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: U…