const和readonly的区别

本文详细对比了C#中的const与readonly修饰符的区别,包括它们的初始化方式、使用场景及灵活性等,有助于理解何时选择使用何种修饰符。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

readonly修饰符用来表示只读,const用来表示不变常量。顾名思义,只读表示不能进行写操作;不变常量不能被修改。这两者到底有什么区别呢

(1) readonly和const都是用来标示常量的。
(2) 初始化赋值不同。
const修饰的常量必须在声明的同时赋值。例如:

public class Class1
{
    public const int MaxValue = 10;       //正确声明
    public const MInValue;                //错误:常量字段要求提供一个值
    public Class1()
    {
        MinValue = 10;
    }
}

readonly字段可以在初始化(声明或构造函数)的过程中赋值。因此,根据所使用的构造函数,readonly字段可能具有不同的值。

public class Class1
{
    public readonly int c = 10;           //正确声明
    public readonly int z;
    public Class1()
    {
        z = 24;//正确
    }
    protected void Load()
    {
        z = 24;//错误:无法对只读的字段赋值(构造函数或变量初始值指定项中除外)
    }
}
readonly是实例成员,所以不同的实例可以有不同的常量值,这是readonly更灵活。

public readonly Color Red = new Color(255, 0, 0);
public readonly Color Green = new Color(0, 255, 0);
public readonly Color Blue = new Color(0, 0, 255);
(3) const字段是编译时常数,而readonly字段可用于运行时常数。
    const要求编译器能够在编译时计算出确定的值。在编译的时候,用计算出的这个确定的值去替换调用该常量的每一个地方。因此不能从一个变量中提取值来初始化常量。
    readonly允许把一个字段设置成常量,但可以执行一些运算,可以确定它的初始值。因为readonly是在计算时执行的,所以可以用某些变量初始化。在运行时才确定的该值。
(4) const默认就是静态的,而readonly如果设置成静态的就必须显示声明。
(5) const修饰的值的类型也有限制,它只能为下列类型之一(或能够转换为下列类型):sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double、decimal、bool、string、enum类型或引用类型。注意能够声明为const的引用类型只能为string或值为null的其他引用类型。readonly可以是任何类型。
这就是说,当我们需要一个const的常量时,若他的类型限制了它不能再编译时被计算出确定的值来,那么我们可采取将之声明为static readonly的方式来解决。但两者之间还是有一点细微的差别的。看下面两个不同的文件。

file1.cs

using System;
namespace MyNamespace1
{
    public class MyClass1
    {
        public static readonly int myField = 10;
    }
}
file2.cs

namespace MyNamespace2
{
    public class MyClass1
    {
        public static void Main()
        {
            Console.WriteLine(MyNamespace1.MyClass1.myField);
        }
    }
}


 两个类分属于两个文件file1.cs和file2.cs,并分开编译。在文件file1.cs内的域myField声明为static readonly时,如果我们由于某种需要将myField的值改为了20,那么我们只需要重新编译文件file1.cs为file1.dll,在执行file2.exe时即会得到20。
    但如果将static readonly改变为const后,再改变myField的初始化值时,我们则必须重新编译所有引用到file1.dll的文件,否则我们引用的MyNamespace1.MyClass1.myField将不会如我们所愿而改变。这在大的系统开发过程中尤其需要注意。
(6) object、Array(数组)和struct(结构)不能被声明为const常量。  




<think>好的,我现在需要回答用户关于TypeScript中constreadonly关键字的区别使用场景的问题。首先,我得回忆一下这两个关键字的基本概念用法。 根据提供的引用资料,const用于声明变量,必须在声明时初始化,并且之后不能重新赋值。比如引用[5]中的例子,const message = 'Hello'之后不能再赋值为'World'。而readonly用于类的属性,可以在构造函数中初始化,确保属性在实例化后不可变。例如引用[3]提到,readonly适用于类属性,允许在构造函数中赋值,之后不能修改。 接下来,我需要整理它们的区别。首先是作用范围的不同:const用于变量,而readonly用于类属性接口/类型别名中的属性。初始化时机方面,const必须在声明时初始化,而readonly可以在声明时或构造函数中初始化。引用[3][5]都强调了这一点。 然后是可变的程度。对于对象或数组,const变量虽然不能重新赋值,但内部属性或元素可以修改。而readonly属性如果是引用类型,同样内部可能可变,但结合readonly修饰符如ReadonlyArray可以禁止修改。引用[4]中的例子展示了如何用泛型创建只读数组,增强不可变性。 使用场景方面,const适用于任何需要不可重新赋值的变量,如配置项或数学常数。而readonly更多用于类或接口中,确保属性在实例化后不变,适合领域模型或DTO。引用[3][4]提到了这些应用场景。 需要确认是否覆盖了所有关键点,比如编译时检查、类型系统中的表现。比如const在编译后会被替换为具体值,而readonly是类型系统的约束,编译后消失。这点引用中没有明确提到,可能需要结合自己的知识补充,但根据现有资料,应该主要依据引用内容。 最后生成相关问题,要基于用户可能感兴趣的方向,比如如何选择两者,实际应用中的注意事项,或者与其他语言类似关键字的对比。确保问题与主题相关,并且有参考资料支持。 总结一下,回答的结构应该是先概述区别,然后详细分点说明,最后给出使用场景示例代码,最后附相关问题。要确保引用正确,比如每个区别点对应的引用编号,并保持语言自然。</think>### TypeScript中constreadonly的差异解析 #### 一、核心区别对比 | 特征 | const | readonly | |--------------------|---------------------------|-------------------------| | **作用对象** | 变量(包括基本/引用类型) | 类属性、接口/类型属性 | | **初始化时机** | 必须声明时初始化 | 可在构造函数中初始化 | | **可变性范围** | 禁止变量重新赋值 | 禁止属性重新赋值 | | **编译后表现** | 替换为具体值(基本类型) | 类型约束(编译时擦除) | | **类型系统支持** | JavaScript原生特性 | TypeScript类型增强特性 | #### 二、具体差异详解 1. **作用范围不同** - const适用于所有变量声明场景,如: ```typescript const PI = 3.1415; // 基本类型 const config = { env: 'prod' }; // 引用类型 ``` - readonly专用于类属性类型定义: ```typescript class User { readonly id: string; // 类属性 constructor(id: string) { this.id = id; } } type Point = { readonly x: number; // 类型属性 } ``` 2. **初始化灵活性差异** const变量必须立即初始化(引用[5]),而readonly属性允许延迟到构造函数: ```typescript class Logger { readonly logPath: string; // ✔️合法 constructor() { this.logPath = '/app.log'; // 构造器内初始化 } } ``` 3. **引用类型处理方式** const变量绑定的是引用地址(可修改内部属性): ```typescript const arr = [1,2,3]; arr.push(4); // ✔️允许操作 ``` readonlyReadonlyArray配合可实现完全不可变: ```typescript const arr: readonly number[] = [1,2,3]; arr.push(4); // ❌编译错误(引用[4]) ``` #### 三、使用场景建议 - **优先使用const的场景** - 全局配置对象(禁止重新赋值) - 数学常数(如$PI = 3.1415$) - 临时计算中间值 - **优先使用readonly的场景** - DTO数据传输对象属性 ```typescript interface ProductDTO { readonly id: string; readonly price: number; } ``` - 类实例标识属性 ```typescript class Order { readonly orderNo: string; constructor(no: string) { this.orderNo = no; // 初始化后不可变
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值