精华内容
下载资源
问答
  • 什么是静态常量(Const)和动态常量(Readonly) 静态常量(Const)和动态常量(Readonly)之间的区别 动态常量(Readonly)被赋值后不可以改变 总结 什么是静态常量(Const)和动态常量(Readonly)  先解释下...

    目录

    什么是静态常量(Const)和动态常量(Readonly)

      先解释下什么是静态常量(Const)以及什么是动态常量(Readonly)。
      静态常量(Const)是指编译器在编译时候会对常量进行解析,并将常量的值替换成初始化的那个值。
      动态常量(Readonly)的值则是在运行的那一刻才获得的,编译器编译期间将其标示为只读常量,而不用常量的值代替,这样动态常量不必在声明的时候就初始化,而可以延迟到构造函数中初始化。

    静态常量(Const)和动态常量(Readonly)之间的区别

     

    静态常量(Compile-time Constant)

    动态常量(Runtime Constant)

    定义

    声明的同时要设置常量值。

    声明的时候可以不需要进行设置常量值,可以在类的构造函数中进行设置。

    类型限制

    只能修饰基元类型,枚举类型或者字符串类型。

    没有限制,可以用它定义任何类型的常量。

    对于类对象而言

    对于所有类的对象而言,常量的值是一样的。

    对于类的不同对象而言,常量的值可以是不一样的。

    内存消耗

    无。

    要分配内存,保存常量实体。

    综述

    性能要略高,无内存开销,但是限制颇多,不灵活。

    灵活,方便,但是性能略低,且有内存开销。

    1. Const修饰的常量在声明的时候必须初始化;Readonly修饰的常量则可以延迟到构造函数初始化 。
    2. Const常量既可以声明在类中也可以在函数体内,但是Static Readonly常量只能声明在类中。Const是静态常量,所以它本身就是Static的,因此不能手动再为Const增加一个Static修饰符。
    3. Const修饰的常量在编译期间就被解析,即:经过编译器编译后,我们都在代码中引用Const变量的地方会用Const变量所对应的实际值来代替; Readonly修饰的常量则延迟到运行的时候。

      举个例子来说明一下:

    View Code

      以上是语法方面的应用,那在实际的用法上,还是有些微妙的变化,通常不易发觉.
      举个例子来说明一下:
      在程序集DoTestConst.dll 中有一个类MyClass,定义了一个公开的静态变量Count

        public static class MyClass
        {
            public const int Count = 10;
        }

      然后另外一个应用程序中引用DoTestConst.dll,并在代码中作如下调用:

        public static void Main(string[] args)
        {
            Console.WriteLine(DoTestConst.MyClass.Count);//输出10
            Console.ReadKey();
        }

      毫无疑问,非常简单的代码,直接输出10。
      接下来更新MyClass的Count的值为20,然后重新编译DoTestConst.dll,并更新到应用程序的所在目录中,注意不要编译应用程序。那么这时候的输出结果按预期那么想应该是20才对,但实际上还是10,为什么呢?
      这就是Const的特别之处,有多特别还是直接看生成的IL,查看IL代码(假设这时候Count的值为10)

      IL_0000: nop
      IL_0001: ldc.i4.s 10
      IL_0003: call void [mscorlib]System.Console::WriteLine(int32)

      红色代码很明显的表明了,直接加载10,没有通过任何类型的加载然后得到对应变量的,也就是说在运行时没有去加载DoTestConst.dll,那么是否意味着没有DoTestConst.dll也可以运行呢?答案是肯定的,删除DoTestConst.dll也可以运行,是否很诡异呢?也就解释了之前的实验,为什么更新Const变量的值之后没有调用新的值,因为程序在运行的时候根本不会去加载DoTestConst.dll。那么10这个值是从哪来的呢?实际上CLR对于Const变量做了特殊处理,是将Const的值直接嵌入在生成的IL代码中,在执行的时候不会再去从dll加载。这也带来了一个不容易发觉的Bug,因此在引用其他程序集的Const变量时,需考虑到版本更新问题,要解决这个问题就是把调用的应用程序再编译一次就ok了。但实际程序部署更新时可能只更新个别文件,这时候就必须用Readonly关键字来解决这个问题。

      接下来看Readonly的版本:

        public static class MyClass
        {
            public static readonly int Count = 10;
        }

      调用方代码不变,接着看生成的IL代码:

      IL_0000: nop
      IL_0001: ldsfld int32 [DoTestConst]DoTestConst.MyClass::Count
      IL_0006: call void [mscorlib]System.Console::WriteLine(int32)

      很明显加载代码变了,一个很常见的ldsfld动作,请求了DoTestConst.MyClass的Count变量,是通过强制要求加载DoTestConst来实现的。因此这时候更新Count的值重新编译之后,还是不编译调用程序,然后再执行就会看到新的值。而这时候如果删除DoTestConst.dll那么,会出现找不到dll之类的异常。这也充分说明了对于Readonly定义的变量是在运行时加载的。

    动态常量(Readonly)被赋值后不可以改变

      ReadOnly 变量是运行时变量,它在运行时第一次赋值后将不可以改变。其中“不可以改变”分为两层意思:

    1. 对于值类型变量,值本身不可以改变(Readonly, 只读)
    2. 对于引用类型变量,引用本身(相当于指针)不可改变。

      值类型变量,举个例子说明一下:

        public class Student
        {
            public readonly int Age;
    
            public Student(int age)
            {
                this.Age = age;
            }
        }

      Student的实例Age在构造函数中被赋值以后就不可以改变,下面的代码不会编译通过:

    Student student = new Student(20);
    student.Age = 21; //错误信息:无法对只读的字段赋值(构造函数或变量初始化器中除外)

      引用类型变量,举个例子说明一下:

        public class Student
        {
            public int Age; //注意这里的Age是没有readonly修饰符的
    
            public Student(int age)
            {
                this.Age = age;
            }
        }
    
        public class School
        {
            public readonly Student Student;
    
            public School(Student student)
            {
                this.Student = student;
            }
        }

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

    School school = new School(new Student(10));
    school.Student = new Student(20);//错误信息:无法对只读的字段赋值(构造函数或变量初始化器中除外)

      引用本身不可以改变,但是引用说指向的实例的值是可以改变的。所以下面的代码是可以编译通过的:

    School school = new School(new Student(10));
    school.Student.Age = 20;

      在构造方法中,我们可以多次对Readonly修饰的常量赋值。举个例子说明一下:

        public class Student
        {
            public readonly int Age = 20;//注意:初始化器实际上是构造方法的一部分,它其实是一个语法糖
    
            public Student(int age)
            {
                this.Age = age;
                this.Age = 25;
                this.Age = 30;
            }
        }

    总结

      Const和Readonly的最大区别(除语法外)
      Const的变量是嵌入在IL代码中,编译时就加载好,不依赖外部dll(这也是为什么不能在构造方法中赋值)。Const在程序集更新时容易产生版本不一致的情况。
    Readonly的变量是在运行时加载,需请求加载dll,每次都获取最新的值。Readonly赋值引用类型以后,引用本身不可以改变,但是引用所指向的实例的值是可以改变的。在构造方法中,我们可以多次对Readonly赋值。

    展开全文
  • 静态常量在程序编译时给值,且在整个程序编译周期内无法改变,无法做到用配置文件给值,较动态常量灵活性不足,但内存消耗非常低。 动态常量在程序运行时给值,且在赋值之后的整个程序运行周期内无法改变,可以做到...

    静态常量在程序编译时给值,且在整个程序编译周期内无法改变,无法做到用配置文件给值,较动态常量灵活性不足,但内存消耗非常低。

    动态常量在程序运行时给值,且在赋值之后的整个程序运行周期内无法改变,可以做到用配置文件给值,灵活性高,但要消耗一定内存。

    一般动态常量的运用比静态常量要多一些。

    展开全文
  • C#拥有两种不同的常量:静态常量(compile-time constants)和动态常量(runtime constants)。它们有不同的特性,错误的使用不仅会损失效率,还可能造成错误。相比之下,静态常量在速度上会稍稍快一些,但是灵活性却...
    C#拥有两种不同的常量:静态常量(compile-time constants)和动态常量(runtime  constants)。它们有不同的特性,错误的使用不仅会损失效率,还可能造成错误。相比之下,静态常量在速度上会稍稍快一些,但是灵活性却比动态常量差很多。 

    //静态常量(隐式是静态的)
    public const int  compiletimeConstant = 1;
    //动态常量
    public static readonly runtimeConstant =  1;

         静态常量在编译时会将其替换为所对应的值,也就是说下面这2句话通过编译器编译后产生的IL是一样的。

    //通过编译后二者会被翻译成相同的中间语言
    int myNum =  compiletimeConstant;
    int myNum = 1;

         动态常量的值是在运行时获得的。IL中将其标为只读常量,而不是用常量的值代替。

         静态常量只能被声明为简单的数据类型(内建的int和浮点型)、枚举或字符串。下面的程序段是通不过编译的。你不能用new关键字初始化一个静态常量,即便是对一个值类型来说。

    //这样是错误的
    public const DateTime myDateTime = new  DateTime(2006,9,1,0,0,0);
    //这样是可以的
    public static readonly DateTime  myDateTime = new DateTime(2006,9,1,0,0,0);

           只读数据也是常量的一种,它们不能在构造器初始化之后被修改。但是它同静态常量不同,它的值是在运行时才被指派的,因此就会获得更大的灵活性。动态常量可以是任意的数据类型。

           二者最大的差别在于:静态常量在编译时会将其换为对应的值,这就意味着对于不同的程序集来说,当你改变静态常量的时候需要将其重新编译,否则常量的值不会发生变化,可能引发潜在的问题,而动态常量就不会有这种情况。

         用const定义的常量(隐式是静态的),需要像访问静态成员那样去访问const定义的常量,而用对象的成员方式去访问会出编译错误。 声明的同时要设置常量值。
          从另一方面来说,如果你的确要声明一些从不改变且处处唯一的常量,例如钩子函数SetWindowsHookEx的idHook参数或序列化时的版本等,就应该使用静态常量。但是用到这样的常量的机会不多。一般来说我们应该使用灵活性更高的动态常量。

                  静态常量           动态常量
     
    内存消耗        无                  因为要保存常量 有消耗
     
    初始化         很少的简单类型,     任意类型,可以在类构造函数中赋值
                   不能new,必须在
                    声明同时赋值
     
    何时发挥作用  编译时进行替换      相当于类中的数据成员
    展开全文
  • C#中动态常量(readonly)与静态常量(const)的区别   C#中有两种常量类型,分别为readonly(运行时常量)与const(编译时常量) Const和Readonly的异同: 相同点:  const和readonly的值一旦初始化则都不再可以...

    C#中动态常量(readonly)与静态常量(const)的区别

     

    C#中有两种常量类型,分别为readonly(运行时常量)与const(编译时常量)

    ConstReadonly的异同:

    相同点:

     const和readonly的值一旦初始化则都不再可以改写;

    不同点:

    1. const定义时必须指定初始值,而readonly定义时可以不进行初始化(MS建议在定义时初始值),同时也可以在构造函数内指定初始值
    2. const隐含static,不可以再写static const;readonly则不默认static,如需要可以写static readonly;

     

    1. const是编译期静态解析的常量(因此其表达式必须在编译时就可以求值,内存无消耗);readonly则是运行期动态解析的常量(内存因保存常量,所以有消耗)
    2. const既可用来修饰类中的成员,也可修饰函数体内的局部变量;readonly只可以用于修饰类中的成员.
    3. const 对于引用类型的常数,可能的值只能是 string 和 null 
         readonly 可以是任何类型
    4. const 默认就是静态的,而 readonly 如果设置成静态的就必须显示声明。
    5. const是编译时常量,readonly是运行时常量;cosnt较高效,readonly较灵活。在应用上以static readonly代替const,以平衡const在灵活性上的不足,

    例:

    Readonly是否可以替换成const

    1. static readonly MyClass myins = new MyClass();
    2. static readonly MyClass myins = null;
    3. static readonly B = 10;   static readonly A = B * 20;
    4. static readonly int [] constIntArray = new int[] {1, 2, 3};

     

    1:不可以 换成constnew操作符是需要执行构造函数的,所以无法在编译期间确定
    2:可以换成const。我们也看到,引用类型的常量 (除了String)只能是Null
    3:可以换成const。我们可以在编译期间很明确的说,A等于200
    4:不可以换成 const 道理和1是一样的,虽然看起来1,2,3的数组的确就是一个常量。

     

     

    展开全文
  • 静态常量和动态常量

    千次阅读 2012-09-02 13:45:56
    动态常量:运行时进行初始化。 区别与联系:   静态常量 动态常量 初始化 声明时初始化 可以在构造方法中初始化 类型限制 类型必须是值类型,且不能通过new来进行初始化 没有限制 ...
  • 最近在学习c#,我在一个类中想调用另一个类的静态常量,可是调用不了,只可以调用动态常量?请问下这是为什么
  • C#中有两种常量类型,分别为readonly(运行时常量)与const(编译时常量),本文将就这两种类型的不同特性进行比较并说明各自的适用场景。 工作原理 readonly为运行时常量,程序运行时进行赋值,赋值完成后便无法更改,...
  • C#中动态常量(readonly)与静态常量(const)的区别   C#中有两种常量类型,分别为readonly(运行时常量)与const(编译时常量) Const和Readonly的异同: 相同点:  const和readonly的值一旦初始化则都不再可以...
  • C#拥有两种不同的常量:静态常量(compile-time constants)和动态常量(runtime constants)。它们有不同的特性,错误的使用不仅会损失效率,还可能造成错误。相比之下,静态常量在速度上会稍稍快一些,但是灵活性却比...
  • C#中含有两种常量:静态常量和动态常量,合适的利用可以提高程序的效率,错误的利用则会增加额外开销,甚至引发错误。  静态常量:const(隐式是静态的)  如 public const int compileData = 1;  动态常量:static...
  • 本文转自:...相比之下,静态常量在速度上会稍稍快一些,但是灵活性却比动态常量差很多。 <br />//静态常量(隐式是静态的) pu
  • 小菜先拙劣的表达一下jvm虚拟内存分布: 程序计数器是jvm执行程序的流水线,存放一些跳转... 方法区存放了一些常量、静态变量、类信息等,可以理解成class文件在内存中的存放位置。 虚拟机堆是jvm执行jav...
  • 1.静态常量 public const int constValue= 1; 静态常量只能声明简单的数据类型,如:整型、浮点型、枚举或字符串。故静态常量属于值类型,不可以用new来初始化静态常量,用const定义的常量需要用访问静态常量的方式...
  • 1. sql 1)sql%rowcount:sql语句执行影响的条数; 2. List item
  • 很明显,系统里面一开始肯定是没有"abcsfsdfsdfsdfsdfsdfsdgsgfdsgdsfsdghgfjghjfdgsdfs"这个常量的,但是随着系统的运行,这个常量出现,先去动态常量池检查是否已经存在,如果存在,则使用已有的,如果不存在,则...
  • php 动态调用常量

    千次阅读 2018-11-07 00:35:46
    情景一,通过 define 定义全局常量 //首先定义了一个叫做 MAXSIZE 的常量 define("MAXSIZE", 100); //定义一个变量,它的值就是 'MAXSIZE' 这个字符串 $str = 'MAXSIZE'; //通过输出 $str 这个...
  • php动态获取常量

    2018-12-17 15:29:00
    class A1{ const V1='100'; const V2='200'; const V3='Hello world'; } $v1 = 'V3'; $a1 = constant('A1::'.$v1);...这个a1就等价于a2,做到动态获取常量的内容 转载于:https://ww...
  • Java常量

    2019-08-18 14:29:45
    常量池分为两种,静态常量池和动态常量池(运行时常量池)。 静态常量池 静态常量池位于Class文件,每一个编译后的类都一个属于自己的静态常量池,用于存放编译期生成的各种字面量和符号引用。当类加载时,这部分...
  • 字符串(String)常量池 字符串常量池存在方法区。...动态常量:保存在Class常量池中的常量,JVM要加载到运行时常量池才能运行。 静态常量:分为String常量和数字常量。小的数字(Short)保存在Class常
  • C#常量

    2019-10-04 21:57:04
    在C#中,常量可以分为静态常量和动态常量。 一、静态常量 声明静态常量的语法格式如下: 修饰符 const 数据类型 常量名 = 常量值;?修饰符:可以是public、protected、internal、private等。 ?const:声明静态...
  • 动态链接与常量

    2020-10-15 21:35:35
    1.每一个栈帧内部都包含一个指向运行常量池该栈帧所属方法的引用,包含这个引用的目的就是为了支持当前的方法代码能够实现动态链接。/ 2.在Java源文件被编译到字节码中时,所有的变量和方法引用都作为符号引用保存在...
  • readonly常量为动态常量;2、const常量在编译时值被确定,在运行时值为编译时值;readonly常量,在编译时为类型的默认值(非指定的默认值),在运行时值被确定;3、const常量无内存消耗;readonly存常量有内存消耗;4、...
  • java常量池概述

    2017-12-06 15:38:09
    Class文件中的常量池(静态常量池,存储在class文件中,就是一段class的代码段);方法区中的运行时常量池(动态常量池,存储在内存中);方法区中的字符串常量池(动态常量池,存储在内存中);
  • C#常量 161019

    2016-10-19 13:53:03
    2 动态常量 readonly readonly 与static配合使用 public static readonly Person persona = new Person();//person是个类, 系统要为readonly所定义的动态常量分配空间,可以在构造函数中进行设定 pub
  • 常量

    2012-02-10 10:08:37
    常量是在编译时已知并在程序的生存期内不发生更改的不可变值。   在程序中使用常量至少有3个好处: A.常量用易于理解的清楚的名称替代了含义不明确的数字或字符串,使程序更易于阅读。 B.常量使程序更易于修改...
  • 基于多常量编码的动态图软件水印保护技基于多常量编码的动态图软件水印保护技术

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 265,713
精华内容 106,285
关键字:

动态常量