C# - readonly 和 const 关键字

引言

程序设计过程中经常会用到常量,C# 语言中有 readonly, const 定义常量,如何准确的定义常量,它们的区别又是什么?

静态常量和动态常量

在了解这两个关键字之前,我们先来了解一下静态常量和动态常量。

  • 静态常量:
    在编译时就确定了值,必须在声明时就进行初始化且之后不能进行更改。
  • 动态常量:
    在运行时确定值,只能在声明时或构造函数中初始化。

const

使用 const 关键字来声明某个常量字段或常量局部变量,是静态常量。 常量字段和常量局部变量不能含变量并且不能修改。 常量可以为数字、布尔值、字符串或 null 引用。 不要创建常量来表示你需要随时更改的信息

const 注意事项

  1. conststatic 不能一起使用,因为常量字段是隐式静态的,const 编译之后就是 static 静态字段。
    在这里插入图片描述

  2. 不能用 new 关键字初始化一个静态常量,即便是对一个值类型来说
    在这里插入图片描述

  3. const 常量不能是变量
    在这里插入图片描述

const 常量访问

类直接访问 const 常量。

namespace ConsoleApp1
{
    class SampleClass
    {
        public int x;
        public int y;
        public const int C1 = 5;
        public const int C2 = C1 + 5;

        public SampleClass(int p1, int p2)
        {
            x = p1;
            y = p2;
        }
    }
    public class TestConst
    {
        public static void Main(string[] args)
        {
            var mC = new SampleClass(11, 22);
            Console.WriteLine($"x = {mC.x}, y = {mC.y}");
            Console.WriteLine($"C1 = {SampleClass.C1}, C2 = {SampleClass.C2}");

        }
    }
}
/* Output
    x = 11, y = 22
    C1 = 5, C2 = 10
*/

readonly

readonly 只能在声明期间或在同一个类的构造函数中向字段赋值。 可以在字段声明和构造函数中多次分配和重新分配只读字段,属于动态常量

static readonly 静态只读字段,只读字段不是隐式静态的,所以要在类级别公开,就必须显式使用 static 关键字。

构造函数退出后,不能分配 readonly 字段。 此规则对于值类型和引用类型具有不同的含义:

  • 由于值类型直接包含数据,因此属于 readonly 值类型的字段不可变。
  • 由于引用类型包含对其数据的引用,因此属于 readonly 引用类型的字段必须始终引用同一对象。 该对象是可变的。 readonly 修饰符可防止字段替换为引用类型的其他实例。 但是,修饰符不会阻止通过只读字段修改字段的实例数据。
    在这里插入图片描述

readonly 常量访问

namespace ConsoleApp1
{
    class SamplePoint
    {
        public int x;
        // Initialize a readonly field
        public readonly int y = 25;
        public readonly int z;
        public static readonly string LAGUAGE = "C#";

        public SamplePoint()
        {
            // Initialize a readonly instance field
            z = 24;
        }

        public SamplePoint(int p1, int p2, int p3)
        {
            x = p1;
            y = p2;
            z = p3;
        }
    }
    public class TestConst
    {
        public static void Main(string[] args)
        {
            Console.WriteLine($"SamplePoint.LAGUAGE = {SamplePoint.LAGUAGE}");
            SamplePoint p1 = new SamplePoint(11, 21, 32);   // OK
            Console.WriteLine($"p1: x={p1.x}, y={p1.y}, z={p1.z}");
            SamplePoint p2 = new SamplePoint();
            p2.x = 55;   // OK
            //p2.y = 66;// Error
            Console.WriteLine($"p2: x={p2.x}, y={p2.y}, z={p2.z}");
        }
    }
}
/* output
SamplePoint.LAGUAGE = C#
p1: x=11, y=21, z=32
p2: x=55, y=25, z=24
*/

const 和 readonly 区别

  1. 概念上的区别
    readonly 表示只读,动态常量,运行时确定值,const 表示静态常量,编译时就确定值。
    比如:人的出生日期就可以定义成 const 常量,值一旦申明就不会发生变化,而人的年龄 age 可以定义成 readonly, 可以在构造函数中根据出生日期计算年龄。
  2. 修饰范围区别
    readonly 只能修饰 field,不能修饰 local variable,const 可修饰 field 和 local variable。
    在这里插入图片描述
  3. 类型区别
    const 只能修饰 primitive type(数字、布尔值,字符) 以及很特殊的引用类型 string 和 null(string是不可变字符串,每次修改,都相当于重新创建了一个),为什么不能修饰其他的引用类型,因为其他的引用类型在编译期不能知道他们的确切值。不能用 new 关键字初始化一个静态常量。
    readonly 可以是任意数据类型,可以用 new 关键字初始化一个动态常量。
  4. const 变量默认是 static 类变量,不能加 static 修饰,readonly 默认不是,需要特意加上 static 才能变成类变量。
  5. 赋值
    const 只能在申明时赋值,不能外部赋值,readonly 可以外部赋值,但只能通过构造函数赋值。
  6. 效率
    const 修饰的常量注重的是效率;readonly 修饰的常量注重灵活。
    const 修饰的常量没有内存消耗;readonly 因为需要保存常量,所以有内存消耗。
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值