转自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. docker guide

    centos docker community version install: yum -y install docker # install docker systemctl start dock ...

  2. Visual Studio 安装VS10x CodeMAP

    最近出差,用的是公司电脑,电脑安装的是Visual Studio 2017 VS10x CodeMap 支持Visual Studio 2010, 2012, 2013, 2015,不支持Visual ...

  3. java中的缓存技术该如何实现

    1缓存为什么要存在?2缓存可以存在于什么地方?3缓存有哪些属性?4缓存介质? 搞清楚这4个问题,那么我们就可以随意的通过应用的场景来判断使用何种缓存了. 1. 缓存为什么要存在?一 般情况下,一个网站 ...

  4. 【MySQL】索引和锁

    前言 本文摘自数据库两大神器[索引和锁] 声明:如果没有说明具体的数据库和存储引擎,默认指的是MySQL中的InnoDB存储引擎 索引 在之前,我对索引有以下的认知: 索引可以加快数据库的检索速度 表 ...

  5. float 和 clear

    float 特性1:可以为行内浮动元素设置宽高 <!DOCTYPE html> <html> <head> <meta charset="UTF-8 ...

  6. terminology(术语)

    1.declaration:告诉编译器某个标识符的name和type,同时略去具体细节. extern int x;     //对象(object)声明式 std::size_t  numDigit ...

  7. Django 多个字段关联同一外键

    # -*- coding: utf-8 -*- """ Tencent is pleased to support the open source community b ...

  8. hdu 1162

    #include<stdio.h> #include<string.h> #include<math.h> #define N 200 #define inf 99 ...

  9. springboot注释详解

    1.属性注入 @ConfigurationProperties(prefix="...") spring会从classpath下的/config目录或者classpath的根目录查 ...

  10. CERC 2014 (动态树+主席树)

    CERC 2014 Pork barrel Problem : n个点m条边有边权的无向图,有q个询问,每次询问权值在[L,R]内的边组成的最小生成树的权值和,强制在线. n <= 1000, ...