readonly 和 const总结

const声明的常量为编译时常量,就是在编译器编译程序时就能够确定值,此后不能改变常量的值
readonly声明的常量为运行时常量,就是在运行时确定值,此后不能改变常量的值
 

声明方式不同:


1:运行时常量只能定义在类或结构体范围中,编译时常量还可以定义在方法中。
2:运行时常量可以是任何类型,编译时常量只能是基本类型(比如 int long等内建整性或浮点型,enum,string)。
3:编译时常量只能在初始化的时候赋值,运行时变量还可以在构造函数中赋值。
4:不能用new操作符来初始化一个编译时常量,即便它的类型是值类型。(这一点有问题,如代码中演示,可以编译通过)
 
最重要的区别:
 
      编译时的常量性能比较好,而运行时常量灵活性比较好,原因是因为编译时常量在编译的时候会被它代表的值代替,运行时常量值是在运行时才被实际赋值。
如果在类的实例中使用readonly值,你可以为一个类的每一个实例设置不同的数据值。而如果用编译时常量,只能通过定义静态常量。
 
使用规则:
 
    当值必须在编译时确定的时候你只能使用const:如属性参数和枚举类型(enum)定义。那些在不同发布版本间定义的值不会发生改变的,也可以用const定义。
    除此之外,最好还是使用增加灵活性的readonly常量吧。
 
附上代码演示:
 // 如果在类的实例中使用readonly值,你可以为一个类的每一个实例设置不同的数据值。而如果用编译时常量,只能通过定义静态常量。
    // 运行时常量可以是任何类型, 编译时常量只能是基本类型

    public class Person
    {
        readonly int id = 0;
        readonly DateTime birthDate = DateTime.Now;  //birthDate不能声明为const

        public Person(int id, DateTime birthDate)
        {
            this.id = id;
            this.birthDate = birthDate;
        }

        public override string ToString()
        {
            return string.Format("Id:{0},BirthDate:{1}", id, birthDate.ToString("yyyy年MM月dd日"));
        }

        //只可以在构造函数中修改或者在声明的时候赋值
        //public void ChangeId(int id)
        //{
        //    this.id = id;
        //}
    }
public class People
    {
        public  const int Age = 10;

        //不可以在构造函数中修改编译时常量
        //public People(int age)
        //{
        //    Age = age;
        //}

        //public void ChangeAge(int age)
        //{
        //    Age = age;
        //}

        public void Test()
        {
            //可以声明在方法中
            const string Message = "Is a message";
            const int year = new Int32();
            Console.WriteLine(Message);

            if (Age <= 10)  //编译时常量在编译的时候会被它代表的值代替,即Age会被10代替
            {
                Console.WriteLine("真年轻哇");
            }
        }

        public override string ToString()
        {
            return string.Format("Age:{0}",Age);
        }
    }
原文地址:https://www.cnblogs.com/supperwu/p/2591530.html