C# 中的readonly属性

例如我们这里有一个类

class TestClass2
    {
        private int someValue;

        public void ChangeValue(int newValue)
        {
            someValue = newValue;
        }

        public int ShowValue()
        {
            return someValue;
        }
    }

而在另一个类中使用它

class TestClass
    {
        private readonly TestClass2 tc; // 注意此处tc是readonly的

        public TestClass()
        {
            tc = new TestClass2();
        }

        public void ChangeTCValue(int value)
        {
            tc.ChangeValue(value);
        }

        public void Show()
        {
            Console.WriteLine("{0}", tc.ShowValue());
        }
    }

 

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

非也!

从上面的代码中我们可以看到,tc的类型是TestClass2,是一个引用类型。而引用类型是必须用new关键字为它分配了一块内存以后它才能在后续代码中工作的。也就是说,tc这个变量仅仅是一块内存地址罢了。这里的“readonly” tc只是无法再重新更改它的引用,但它所引用对象的属性是可以改变的。

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

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

当然,这里的“地址不能修改”指的是在代码中不能再对readonly变量进行再赋值,实际运行情况中可能会遇到GC或反射改变内存的情况。但是在本文所说的环境下不必考虑。

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

posted @ 2019-02-18 11:24  沙耶  阅读(8262)  评论(0编辑  收藏  举报