zoukankan      html  css  js  c++  java
  • string 是值类型,还是引用类型(.net)[转]

    转自http://hi.baidu.com/newfzks/item/b805f0f4edb0810dd89e7290

    string 是值类型,还是引用类型(.net)

    一. string 类型的用法比较像值类型

    稍微有点.NET 编程知识的人都知道 string是引用类型。我为什么还有此一问?因为string的使用非常像值类型。举个例子:

     string str = "abc";
     Test(str);
     MessageBox.Show(str);


     private void Test(string str)
     {
          str = str + "de";
     }

    运行上面的代码你会发现 str始终是abc,这就有点像值类型。因为值类型传递的是具体的值,所以传入的参数是形参,函数内部修改形参,不影响外部的变量。引用类型可不是这样,传递的是引用不是值。所以函数内部的修改,会影响到外部。看这个例子:
      List<string> lst = new List<string>();
      Test2(lst);
      MessageBox.Show(lst.Count.ToString());

      private void Test2(List<string> lst)
      {
          lst.Add("abc");
          lst.Add("de");
      }

    你会发现Test2已经修改了lst,使其count数变为了2。

    二.string类型是只读的引用类型,修改string对象会创建新的实例

    到底string类型是值类型还是引用类型?答案当然是引用类型。通过以下代码即可验证:
     string str = "abc";
     //1
     MessageBox.Show(str.GetHashCode().ToString());
     Test(str);
     //4
     MessageBox.Show(str.GetHashCode().ToString());


     private void Test(string str)
     {
          //2
          MessageBox.Show(str.GetHashCode().ToString());
          str = str + "de";
          //3
          MessageBox.Show(str.GetHashCode().ToString());
      }
     可以看出 第一个提示框和第二个提示框的显示的值是一样的,说明了string传递的是引用,也就是指针(地址)。 第三个提示框的数值 和第二个提示框的值不一样。为什么是这样?
     查 MSDN 可以找到 答案:
        String 对象称为不可变的(只读),因为一旦创建了该对象,就不能修改该对象的值。看来似乎修改了 String 对象的方法实际上是返回一个包含修改内容的新 String 对象。  

    str = str + "de"; 由于string不可变,连接字符串操作已经创建了一个新的string对象。
     

    三.参数的按值传递,和按引用传递

    为什么第四个提示框和第三个提示框不一样,而是和第一个提示框相同呢?
      要弄明白这个问题,需要弄明文.NET中函数的参数是怎么传递的。
     在.net中参数传递有两种传递方式,传值,传引用。默认情况下是传值。对于引用类型,传值会确保参数的引用(地址)不会发生改变。即便更改了对象的引用,在函数内部会认为只是更改了参数的副本。相当于声明了一个局部变量。 函数结束时,局部变量生命周期结束,变量还是原来的值。

    如果这样操作lst,你就会知道 什么时候变量的引用发生了改变。
      List<string> lst = new List<string>();
      Test2(lst);
      MessageBox.Show(lst.Count.ToString());


     private void Test2(List<string> lst)
     {
         lst.Add("abc");
         lst.Add("de");
         lst = new List<string>();
     }

    lst的count数并不会因为 在test2中重新 new 了一个 新的lst而变为0。因为传值操作不允许改变参数的引用。new 一个新实例,重新开辟了一个内存空间,引用已经发生了改变。而lst.Add操作,不会创建新的lst,引用没有改变。

    如果是传引用(c#函数声明调用加 ref,vb函数需声明 byref),则没有这个限制,可以更改参数的引用。
    代码若改成这样
    string str = "abc";
    Test(ref str);
    MessageBox.Show(str);

    private void Test(ref string str)
    {
         str = str + "de"; 
    }
    你会发现弹出的提示框会显示为abcdef,此时要注意,这是传引用,而且在提示框那句代码中str已经和初始化时的str相比,引用已经改变,是一个新sring。

    对于值类型的参数,传值,传递的是具体的数值;传引用,传的是变量的引用(这点和引用类型 是一样的)。

  • 相关阅读:
    探索SaaS产业发展新机遇|鲁班会贵安首秀圆满收官
    带你认识三种kafka消息发送模式
    常用的echo和cat,这次让我折在了特殊字符丢失问题上
    当MySQL执行XA事务时遭遇崩溃,且看华为云如何保障数据一致性
    一图解析MySQL执行查询全流程
    HDFS源码解析:教你用HDFS客户端写数据
    大型集团企业云管平台建设参考架构
    带你了解家居智能的心脏:物联网关
    带你认识7种云化测试武器
    实践解析可视化开发平台FlinkSever优势
  • 原文地址:https://www.cnblogs.com/ylemzhang/p/3392862.html
Copyright © 2011-2022 走看看