zoukankan      html  css  js  c++  java
  • 对于string是值类型还是引用类型的思考

    当然了,string本质上肯定是引用类型,但是这个特殊的类却表现出值类型的特点:

    判断相等性时,是按照内容来判断的,而不是地址

    它肯定是一个引用类型没错,两个方面来看:

    1. class string继承自object,而不是System.ValueType(Int32这样的则是继承于System.ValueType)
    2. string本质上是个char[],而Array是引用类型,并且初始化时也是在托管堆分配内存的

    微软设计这个类的时候估计是为了方便操作,所以重写了操作符和Equals方法,不然的话我们判断string相等得这样:

    foreach(char c in s.ToCharArray()){...}

    但是另外一个常用的对象微软却没有帮忙重写等值判断的方法:Array

    这样int[] a = {1,2,3}和int b = {1,2,3},a == b?// false

    还有一个容易搞错的地方是按引用传递还是按值传递的问题:

    引用类型按引用传递,值类型按值传递,这些都不错。
    一个引用类型,比如System.Array类,作为参数向一个方法传递时,传送的是指针,但是这两种代码是不是就意味着等效?

    void Test(Array a)和void Test(ref Array a)

    结果是并不完全等效。

    如果在函数内部调用构造函数新建了对象并赋予参数,则函数外的变量不会受影响;
    比如a = new ...

    如果只是改动该参数(一个对象)的字段,则会有影响,此时加不加ref都是等效的。
    比如a[i] = ...

    而string类型的另外一个特殊性在于它是“不会变”的,每次操作string,都相当于新建了一个string对象,所以对于string来讲,void Test(String s)和void Test(ref String s)永远都是不一样的。在这里string再次表现出了值类型的特点,我们以为这是传值 - 实际上传送的还是地址,但是在操作的时候string被再次初始化,外部根本不能得到这个变化。

    对于变量作用域的概念来讲,微软这么设计也是合理的:既然是函数内部建立的对象,外部就应该没有访问这个对象的能力,函数结束后,这些对象就会被GC收集,同样不会影响外面的程序。

    推荐看一下王涛的《你必须知道的.NET》这本书,里面的“值类型与引用类型”、“参数之惑”等可以深度的解决这问题。

    地址:http://www.cnblogs.com/anytao/archive/2007/09/14/must_net_catalog.html

  • 相关阅读:
    HDU 1525
    kmp模板
    hdu 4616 Game(树形DP)
    hdu 4619 Warm up 2(并查集活用)
    hdu 4614 Vases and Flowers(线段树加二分查找)
    Codeforces 400D Dima and Bacteria(并查集最短路)
    poj 2823 Sliding Window (单调队列)
    hdu 2196 Computer(树形dp)
    hdu 4604 Deque
    最短路径
  • 原文地址:https://www.cnblogs.com/SALIN/p/1261674.html
Copyright © 2011-2022 走看看