• C# readonly和const


    const效率高,readonly更灵活

    区别:

    1、const是一个编译期常量,readonly是一个运行时常量

    2、const只能修饰基元类型、枚举类型或字符串类型,readonly没有限制

    const天然就是static的,不能手动为const添加一个static修饰符:

    static const int ConstValue = 100;//编译错误:常量“ConstValue”不能标记为 static    

    const效率高是因为经编译后,在代码中引用const变量的地方会用const变量所对应的实际值来代替,如:

    1  Console.WriteLine(ConstValue);
    2  Console.WriteLine(100);
        IL_0000: nop
        IL_0001: ldc.i4.s  100
        IL_0003: call      void [mscorlib]System.Console::WriteLine(int32)
        IL_0008: nop
        IL_0009: ldc.i4.s  100
        IL_000B: call      void [mscorlib]System.Console::WriteLine(int32)

    第一行代码和第二行代码生成的IL代码时一致的。

    readonly变量时运行时变量,其赋值行为发生在运行时,它在第一次赋值后将不可改变:

    1)对于值类型变量,值本身不可改变。

    2)对于引用类型变量,引用本身(相当于指针)不可改变。

    例1:readonly修饰值类型变量

     1     static void Main(string[] args)
     2     {
     3         Student student = new Student(18);//传值18
     4         student.age = 20;//编译不通过,无法对只读的字段赋值(构造函数或变量初始值指定项中除外)    
     5     } 
     6 
     7     class Student
     8     {
     9         public readonly int age;
    10         public Student(int value)
    11         {
    12             age = value;//给只读变量赋值18
    13         }
    14     }

    student实例在构造方法对只读变量age进行赋值,赋值后不可改变,所以第4行代码编译不通过。

    例2:readonly修饰引用类型编写

     1     class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5             Sample sample = new Sample(new Student(18));
     6             sample.student.age = 20;//编译通过,允许修改age
     7             //sample.student = new Student(20);//编译不通过,无法对只读的字段赋值(构造函数或变量初始值指定项中除外)
     8         }
     9     }
    10     class Sample
    11     {
    12         public readonly Student student;
    13         public Sample(Student value)
    14         {
    15             student = value;
    16         }
    17     }
    18     class Student
    19     {
    20         public int age;
    21         public Student(int value)
    22         {
    23             age = value;//给只读变量赋值18
    24         }
    25     }

    因为引用本身不可变,所以第7行代码编译不通过,指向的实例不可变;但是所指的实例的值却是可以改变的,所以第6行代码编译可以通过。

    readonly所代表的运行时含义有一个重要的作用,就是可以为每个类的实例指定一个readonly变量。

    例3:

     1     class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5             Student student = new Student(18);
     6         }
     7     }
     8     class Student
     9     {
    10         public readonly int age = 0;
    11         public Student(int value)
    12         {
    13             age = value;
    14         }
    15     }

    例3的代码是可以运行的,age首先在初始化时被初始化器赋值为0,然后,student实例化时,在构造方法中又被赋值为18。实际上,应该把初始化器理解成构造方法的一部分,它其实是一个语法糖。在构造方法内,可以多次对readonly赋值。

    参考:《编写高质量代码改善C#程序的157个建议》陆敏技

  • 相关阅读:
    tensorflow学习3---mnist
    tensorflow学习2-线性拟合和神经网路拟合
    关于泛型数据结构中OrderBy的使用
    敏捷开发之观察者模式
    敏捷开发之设计文档
    C#算法实现获取树的高度
    武林高手?敏捷开发,唯velocity取胜
    C#接口多继承方法重名问题
    .Net平台技术栈?不止于此
    浅谈C#中Tuple和Func的使用
  • 原文地址:https://www.cnblogs.com/xuyouyou/p/13158144.html
Copyright © 2020-2023  润新知