• C#中的readonly


    C#中的readonly

    const 定义的是静态常在对象初始化的时候赋值.以后不能改变它的值.属于编译时常量。不能用new初始化。

    Readonly 是只读变量.属于运行时变量.可以在类constructor里改变它的值.不能作用于局部变量。

    const 和 static 不能在一起用,它已经是静态的了。

    我们都知道,const和static readonly的确非常像:通过类名而不是对象名进行访问,在程式中只读等等。在多数情况下能混用。
    二者本质的差别在于,const的值是在编译期间确定的,因此只能在声明时通过常量表达式指定其值。

    而static readonly,在程式中只读, 不过它是在运行时计算出其值的,所以还能通过静态构造函数来对它赋值,

    readonly只能用来修饰类的field,不能修饰局部变量,也不能修饰property等其他类成员.

    明白了这个本质差别,我们就不难看出下面的语句中static readonly和const能否互换了:

    1.  
      1. static readonly MyClass myins = new MyClass();
    2.  
      2. static readonly MyClass myins = null;
    3.  
      3. static readonly B = 10; static readonly A = B* 20;
    4.  
      4. static readonly int[] constIntArray = new int[] { 1, 2, 3 };
    5.  
      5. void SomeFunction()
    6.  
      {
    7.  
      const int a = 10;
    8.  
      .........
    9.  
      }
    1:不能换成const。new操作符是需要执行构造函数的,所以无法在编译期间确定
    2:能换成const。我们也看到,Reference类型的常量(除了String)只能是Null。
    3:能换成const。我们能在编译期间非常明确的说,A等于200。
    4:不能换成const。道理和1是相同的,虽然看起来1,2,3的数组的确就是个常量。
    5:不能换成readonly,readonly只能用来修饰类的field,不能修饰局部变量,也不能修饰property等其他类成员。
    1.  
      using System;
    2.  
      using System.Collections.Generic;
    3.  
      using System.Linq;
    4.  
      using System.Text;
    5.  
      using System.Threading.Tasks;
    6.  
       
    7.  
      namespace ConsoleApplication1
    8.  
      {
    9.  
      //定义一个类
    10.  
      class Class1
    11.  
      {
    12.  
      int value;
    13.  
      public void ChangeValue1(int _value)
    14.  
      {
    15.  
      value = _value;
    16.  
      }
    17.  
      public void ShowValue1()
    18.  
      {
    19.  
      Console.WriteLine(value);
    20.  
      }
    21.  
      }
    22.  
      //再定义一个类,把第一个类作为变量
    23.  
      class Class2
    24.  
      {
    25.  
      readonly Class1 class1;//注意是readonly
    26.  
       
    27.  
      public Class2() { class1 = new Class1(); }
    28.  
       
    29.  
      public void ChangeValue2(int _value)
    30.  
      {
    31.  
      class1.ChangeValue1(_value);//
    32.  
      }
    33.  
      }
    34.  
      class Program
    35.  
      {
    36.  
      static void Main(string[] args)
    37.  
      {
    38.  
       
    39.  
       
    40.  
       
    41.  
      }
    42.  
      }
    43.  
      }

    我们看到虽然class1这个字段是readonly的,但是可以使用方法来改变value的值。似乎这个“只读”失去了意义,因为可以修改它的值的话还叫什么“只读”呢?

    非也!

    从上面的代码中我们可以看到,class1的类型是Class1,是一个引用类型。而引用类型是必须用new关键字为它分配了一块内存以后它才能在后续代码中工作的。也就是说

    ,class1这个变量仅仅是一块内存地址罢了。

    也就是说,这里的“readonly” class1只是无法再重新更改它的引用,但它所引用对象的属性是可以改变的。

    那么为什么不用const呢?还是因为class1是引用,是动态分配内存的,不可能在编译阶段就确定它的地址,这点和值类型(包括string)是完全不一样的。

    综上所述,可以得出结论: readonly修饰的字段,其初始化仅是固定了其引用(地址不能修改),但它引用的对象的属性是可以更改的。

    所以,大胆放心的用readonly吧,这样还可以防止不必要的再赋值,保证了这个对象的安全性。

    1.  
      using System;
    2.  
      using System.Collections.Generic;
    3.  
      using System.Linq;
    4.  
      using System.Text;
    5.  
      using System.Threading.Tasks;
    6.  
       
    7.  
      namespace ConsoleApplication1
    8.  
      {
    9.  
      //定义一个类
    10.  
      class Class1
    11.  
      {
    12.  
      public readonly int value;
    13.  
       
    14.  
      public Class1(int _value)
    15.  
      {
    16.  
      value = _value;//right,只能通过构造函数来对value赋值
    17.  
      }
    18.  
       
    19.  
      public void ChangeValue1(int _value)
    20.  
      {
    21.  
      value = _value;//error
    22.  
      }
    23.  
       
    24.  
      }
    25.  
       
    26.  
      class Program
    27.  
      {
    28.  
      static void Main(string[] args)
    29.  
      {
    30.  
       
    31.  
      Class1 one = new Class1(2);
    32.  
      int b = 2;
    33.  
      one.value = b;//error
    34.  
      }
    35.  
      }
    36.  
      }



  • 相关阅读:
    tabbar 旋转指定的页面
    GDAL中文路径不能打开&Shp文件字段属性值中文乱码
    Project : error PRJ0019: 工具从"Moc'ing xxx.h..."
    详解Android中的屏幕方向
    qt中获取文件路径和文件名
    vs2005下Qt项目中修改exe图标的方法
    Qt & C/C++统计运行时间
    Qt 中Treewidget添加右键菜单
    QT 中文乱码解决方案
    Qt多线程应用QRunnable显示进度条示例
  • 原文地址:https://www.cnblogs.com/sexintercourse/p/16318225.html
Copyright © 2020-2023  润新知