C# - readonly 和 const 关键字

C# - readonly 和 const 关键字

  • 引言
  • 静态常量和动态常量
  • const
    • const 注意事项
    • const 常量访问
  • readonly
    • readonly 常量访问
  • const 和 readonly 区别

引言

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

静态常量和动态常量

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

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

const

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

const 注意事项

  1. conststatic 不能一起使用,因为常量字段是隐式静态的,const 编译之后就是 static 静态字段。
    C# - readonly 和 const 关键字_第1张图片

  2. 不能用 new 关键字初始化一个静态常量,即便是对一个值类型来说
    C# - readonly 和 const 关键字_第2张图片

  3. const 常量不能是变量
    C# - readonly 和 const 关键字_第3张图片

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 修饰符可防止字段替换为引用类型的其他实例。 但是,修饰符不会阻止通过只读字段修改字段的实例数据。
    C# - readonly 和 const 关键字_第4张图片

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。
    C# - readonly 和 const 关键字_第5张图片
  3. 类型区别
    const 只能修饰 primitive type(数字、布尔值,字符) 以及很特殊的引用类型 string 和 null(string是不可变字符串,每次修改,都相当于重新创建了一个),为什么不能修饰其他的引用类型,因为其他的引用类型在编译期不能知道他们的确切值。不能用 new 关键字初始化一个静态常量。
    readonly 可以是任意数据类型,可以用 new 关键字初始化一个动态常量。
  4. const 变量默认是 static 类变量,不能加 static 修饰,readonly 默认不是,需要特意加上 static 才能变成类变量。
  5. 赋值
    const 只能在申明时赋值,不能外部赋值,readonly 可以外部赋值,但只能通过构造函数赋值。
  6. 效率
    const 修饰的常量注重的是效率;readonly 修饰的常量注重灵活。
    const 修饰的常量没有内存消耗;readonly 因为需要保存常量,所以有内存消耗。

你可能感兴趣的:(C#,c#,开发语言,const,readonly,常量)