zoukankan      html  css  js  c++  java
  • 关键字const和readonly的区别

    const和readonly都是给字段设置常量。何谓常量,是指在程序中直接给出其值,在整个操作过程中其值保持不变的数据。

    const关键字是静态常量,在编译时就初始化好,对于每一次编译后的结果,const的值是固定的,它指定的全局变量或局部变量的值不能被修改。

    而readonly的值是可以在运行的时候才确定值的~~

    使用场景 

    1、const定义常量后,是一个固定的硬编码值,不允许再次修改,而readonly允许在类的构造函数中进行再次赋值

    2、在不同类实例中有不同的实例变量,实例变量可以采用readonly

    static readonly

    const 是编译时常量,readonly 是运行时常量,const 较高效,readonly更灵活,在应用上一般都以 static readonly 来代替const,以平衡const在灵活性上的不足,所以static readonly等效于const。

    static readonly允许在类的静态构造函数中进行赋值

    const比readOnly效率高

    因为const变量经过编译器编译后,我们在代码中引用const变量的地方会用const变量所对应的实际值来代替

    const int value = 1000;
    Console.WriteLine(value);

    和下面代码所生成代码的IL是一致的

    Console.WriteLine(1000);

    readonly比const灵活

    字段声明为const,则它不是一个变量,而是一个笃定的硬编码值 ,它是隐式static的
    readOnly允许把一个字段设置为常量,但也可以执行一些运算,以确定她的初始值。可以在构造函数中给readonly字段赋值,但不能在其它地方。 它还可以是个实例变量而不static的,每个类都有不同的值 ,和const不同,要定义为static,必须显式的声明

    class Program
    {
      static readonly int readValue = 2000;

      static Program()
      {
        readValue = 55; //只能在构造函数上下文中给它赋值
      }

      static void Main(string[] args)
      {
        Console.WriteLine(readValue);
      }
    }

    readonly变量是运行时变量,其赋值行为发生在运行时。readonly的全部意义在于,它在运行时第一次被赋值后将不可以改变。当然,“不可以改变”分为两层意思:
    1)对于值类型变量,值本身不可改变(readonly,只读)。
    2)对于引用类型变量,引用本身(相当于指针)不可改变。
    首先我们来看值类型变量,如下代码:

    public class Sample
    {
        public readonly int readValue;
        public Sample(int value)
        {
             readValue = value;
        }
    }            

    Sample的实例readValue在构造方法中被赋值后就不可以改变,下面的代码将不会编译通过

    Sample sample = new Sample(100);
    //sample.intValue = 18; //无法对只读的字段赋值(构造函数或变量初始值指定项中除外)
    Console.WriteLine(sample.readValue);

    readonly所代表的运行时含义有一个重要的作用,就是可以为每个类的实例指定一个readonly的变量。以Sample这个类为例,可以在运行时生成多个实例,而同时,又可以为每个实例生成自己的readonly变量,如下:

    Sample sample = new Sample(100);
    Sample sample = new Sample(200);
    Sample sample = new Sample(300);

    针对引用类型变量,如下代码

    public readonly Student student;
    public Sample(Student value)
    {
         student = value;
    }

    Sample的ReadOnlyValue是一个引用类型变量,赋值后,变量不能再指向任何其他的Student实例,所以,下面的代码将不会编译通过:

    Sample sample = new Sample(new Student() { Id = 1, name = "张小三" });
    //sample.student = new Student() { Id = 2, name = "张小四" }; //无法对只读的字段赋值(构造函数或变量初始值指定项中除外)
    Console.WriteLine(sample.student.name);

    但是,我们之前已经提到过了,引用本身不可改变,引用所指的实例的值,却是可以改变的,下面的代码将会被允许:

    Sample sample = new Sample(new Student() { Id = 1, name = "张小三" });
    sample.student.name = "张小四";
    Console.WriteLine(sample.student.name);

    const和readonly区别:

    名称

    静态常量(Const)

    动态常量/只读变量(Readonly)

    使用范围

    全局和局部

    全局

    初始值

    定义时必须赋初始值

    定义时可不赋值

    赋值方式

    定义时赋值

    定义时赋值、构造函数中赋值

    访问方式

    类型访问

    实例对象访问

    Static

    默认就是static,不需要显式声明

    可以和Static 同时使用,使用后,如果想在构造函数中赋初始值,必须使用静态无参构造函数。

    应用类型

    只能应用值类型和string类型

    任意类型

    题外话:静态构造函数和普通构造函数哪个先执行?

    class Sample
    {
         public Sample()
         {
              Console.WriteLine("普通构造函数");
         }
    
         static Sample()
         {
              Console.WriteLine("静态构造函数");
         }
    }
    输出打印结果:
    普通构造函数
    静态构造函数
    
    
  • 相关阅读:
    NET在后置代码中输入JS提示语句(背景不会变白)
    陈广老师C#参考视频 方法的参数传递 总结
    preventDefault和stopPropagation两个方法的区别
    zerobased budgeting: 零基预算法
    JS: 关于自执行的匿名函数(整理)
    通过实例理解javascript 的call()与apply()
    setTimeout注意几点
    js constructor
    canphp的数据库操作
    JS事件监听器
  • 原文地址:https://www.cnblogs.com/zxh8080/p/14256498.html
Copyright © 2011-2022 走看看