• Readonly and Mutable, vs. Read / Write Properties


    刚刚逛Bill Wanger的blog看到了一篇帖子,虽然感觉没什么新意,不过既然他老人家郑重其事地提出来了,估计有他的用意,自己写了个程序验证了一下,贴在下面,由于他老人家用的是C#2.0(用到了范型),俺机子没有装,只能把它翻译成C#1.1的版本了.
    class ClassPrint
        
    {
            
    private readonly ArrayList words;
            
    public ClassPrint(ArrayList _words)
            
    {
                words 
    = _words;
            }

            
            
    public void printTheWords()
            
    {
                
    foreach(object _word in words)
                
    {
                    Console.WriteLine(_word.ToString());
                    Console.WriteLine();
                }

                Console.ReadLine();
            }

            
    static void Main(string[] args)
            
    {
                ClassWords testWords 
    = new ClassWords();
                ClassPrint testPrint 
    = new ClassPrint(testWords._pWords);
                
    //The First Example
                testWords._pWords.Add("The First Example:\n");
                testWords._pWords.Add(
    "I become a uncle today!");
                testPrint.printTheWords();

                
    //The Second Example
                testWords._pWords = new ArrayList();
                testWords._pWords.Add(
    "The Second Example:\n");
                testWords._pWords.Add(
    "I am very happy now!");
                testPrint.printTheWords();

            }

            
        }


        
    class ClassWords
        
    {
            
    private ArrayList words = new ArrayList();
            
    public ArrayList _pWords
            
    {
                
    get
                
    {
                    
    return words;
                }

                
    set
                
    {
                    words 
    = value;
                }

            }

        }

    代码很简单,随便看看就懂了.
    Bill Wanger的意思是如果不通过编译器仅仅通过大脑去思考的话,很多程序员会以为是如下输出:
    The First Example:
    I become a uncle today!
    The Second Example:
    I am very happy now!
    实际的输出应该为
    The First Example:
    I become a uncle today!
    The First Example:
    I become a uncle today!

    这个其实很好理解,负责输出的classPrint的words是readonly的只能在声明或者构造函数中为其赋值,这个字段在构造函数中被指定为一块内存区域,就不会再做更改.当然这个地方的words字段即使不是readonly的输出结果还是一样的,因为它指向的内存区域跟_pWords已经不一样的,_pWords已经指向了另一段内存区域,它的更改并不会影响到words.
    上面扯了半天好像离Bill Wanger的意思越来越远了,哈哈.还是说一下他的意思吧.
    Bill Wanger的意思是,下面的定义

    private ArrayList words = new ArrayList();
            
    public ArrayList _pWords
            
    {
                
    get
                
    {
                    
    return words;
                }

            }

    叫做易变(Mutable)只读属性,可以改变该属性的状态,但不能替换它,比如可以用Add(),Remove(),Clear()方法来改变ArrayList属性的状态,但不能让其指向另一个ArrayList.
    但是

    private ArrayList words = new ArrayList();
            
    public ArrayList _pWords
            
    {
                
    get
                
    {
                    
    return words;
                }

                
    set
                
    {
                    words 
    = value;
                }

            }

    却可以让它指向另一个ArrayList,这样如果一个客户端代码已经缓存了这个属性原始数据的引用,如果用set方法让它指向新的ArrayList就会显得很突然和奇怪.
    我觉得这其实是很正常和比较好理解的,如果类在设计的时候不允许它再指向新的ArrayList(当然这里的Mutable,可以指任何引用类型的数据,比如DataSet等等),那就把这个字段设计为只读,如果所有的实例只允许一份值拷贝,干脆用Sington Pattern.
    Bill Wanger写的<<Effective C#>>和<<The C# Core Language Little Black Book>>据说很经典,等看完Anders就可以看这两本了,爽.


  • 相关阅读:
    dockerfile 镜像 指定虚拟机的内存
    springBoot整合MongoDB(动态查询)
    ubuntu 使用sudo apt-get update命令的时候会报http://archive.ubuntukylin.com:10006/ubuntukylin/dists/xenial/InRelease 无法连接
    在Ubuntu下进行MongoDB安装步骤
    艺术和代码的结合 turtle + python 的结合
    MySQL CPU性能定位
    送书丨《架构解密:从分布式到微服务》
    区块链在天猫国际商品溯源中的应用
    nginx gzip
    别被忽悠了!阿里内部人士:我们正悄悄地拆掉中台,你还在建?
  • 原文地址:https://www.cnblogs.com/Farseer1215/p/280808.html
Copyright © 2020-2023  润新知