转自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。

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

string 是值类型,还是引用类型(.net)[转]的更多相关文章

  1. String为值类型还是引用类型

    关于String为值类型还是引用类型的讨论一直没有平息,最近一直在研究性能方面的问题,今天再次将此问题进行一次明确.希望能给大家带来点帮助. 如果有错误请指出. 来看下面例子: //值类型 int a ...

  2. 转:C# String为值类型还是引用类型

    关于String为值类型还是引用类型的讨论一直没有平息,最近一直在研究性能方面的问题,今天再次将此问题进行一次明确.希望能给大家带来点帮助,如果有错误请指出. 来看下面例子: //值类型 int a ...

  3. C# 值类型和引用类型

    一.基本概念 C#只有两种数据类型:值类型和引用类型 值类型在线程栈分配空间,引用类型在托管堆分配空间 值类型转为引用类型称成为装箱,引用类型转为值类型称为拆箱 以下是值类型和引用类型对照表 从上图可 ...

  4. 值类型与引用类型(特殊的string) Typeof和GetType() 静态和非静态使用 参数传递 相关知识

    学习大神博客链接: http://www.cnblogs.com/zhili/category/421637.html 一 值类型与引用类型 需要注意的string 是特殊类型的引用类型. 使用方法: ...

  5. 【译】.NET中六个重要的概念:栈、堆、值类型、引用类型、装箱和拆箱

    为何要翻译 一来是为了感受国外优秀技术社区知名博主的高质量文章,二来是为了复习对.NET技术的基础拾遗达到温故知新的效果,最后也是为了锻炼一下自己的英文读写能力.因为是首次翻译英文文章(哎,原谅我这个 ...

  6. 图解C#的值类型,引用类型,栈,堆,ref,out

    C# 的类型系统可分为两种类型,一是值类型,一是引用类型,这个每个C#程序员都了解.还有托管堆,栈,ref,out等等概念也是每个C#程序员都会接触到的概念,也是C#程序员面试经常考到的知识,随便搜搜 ...

  7. JAVA初学(1):值类型和引用类型的区别

    JAVA值类型和引用类型的区别(转)                                                          [定义] 引用类型表示你操作的数据是同一个,也就 ...

  8. .NET面试题解析(01)-值类型与引用类型

      系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 常见面试题目: 1. 值类型和引用类型的区别? 2. 结构和类的区别? 3. delegate是引用类型还 ...

  9. Emit学习(2) - IL - 值类型和引用类型(补)

    上周末回家去享受生活了, 工作是为了更好的生活嘛, 所以我把生活, 工作分的比较开. 这几天不是很忙, 在学习工作技能的同时, 发点博文, 也算是做一个学习笔记 上篇中, 贴出的地址里面那位哥, 也有 ...

随机推荐

  1. 获得Dictionary所有key和value值

    Dictionary<string, string> dc = new Dictionary<string, string>(); dc.Add("code" ...

  2. uncategorized SQLException for SQL []; SQL state [99999]; error code [17004]; 无效的列类型: 1111; nested exception is java.sql.SQLException: 无效的列类型: 1111

    WHERE 的条件取值时添加上jdbcType=NUMBER这样的配置 参考[1]:https://blog.csdn.net/fyhjuyol/article/details/45483167

  3. 【三种负载均衡器的优缺点】LVS Nginx HAProxy

    搭建负载均衡高可用环境相对简单,主要是要理解其中原理.此文描述了三种负载均衡器的优缺点,以便在实际的生产应用中,按需求取舍. 目前,在线上环境中应用较多的负载均衡器硬件有F5 BIG-IP,软件有LV ...

  4. [转]Selenium-Webdriver系列Python版教程(1)————快速开始

    elenium的历史,selenium2与WebDriver的关系本文就不讲了,想了解的同学们百度一下就可以Ok.     本系列教程是以Selenium-WebDriver的Python版本,首先从 ...

  5. HDU 5468 Puzzled Elena

    Puzzled Elena Time Limit: 2500ms Memory Limit: 131072KB This problem will be judged on HDU. Original ...

  6. HDU1166-敌兵布阵,线段数模板题~~

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  7. NOIP2009T3最优贸易(Dfs + spfa)

    洛谷传送门 看到这个题,原本想先从后往前dfs,求出能到终点的点,再在这些点里从前往后spfa,用一条边上的两个城市的商品价格的差来作边权,实施过后,发现图中既有负边权,又有回路,以及各种奇奇怪怪的东 ...

  8. 最长递增子序列 (LIS) Longest Increasing Subsequence

    问题描述: 有一个长为n的数列a0, a1,..., an-1.请求出这个序列中最长的上升子序列.请求出这个序列中最长的上升子序列. 上升子序列:对于任意i<j都满足ai<aj的子序列. ...

  9. [NOIP2003] 提高组 洛谷P1041 传染病控制

    题目背景 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国大范围流行,该国政府决定不惜一切代价控制传染病的蔓延.不幸的是,由于人们尚未完全认识这种传染病,难以准确判别病毒携带 ...

  10. Codevs 1688 求逆序对

     时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 给定一个序列a1,a2,…,an,如果存在i<j并且ai>aj,那么我 ...