1.    值类型与引用类型比较

classProgram

{

staticvoid Main()

{

int b = a;   //将a的副本给变量b

b = 10;

Console.WriteLine(string.Format("a={0},b={1}", a, b));

Person ZS = newPerson();       //张三

Person SM = ZS;        //三毛等于张三,即张三和三毛就是同一个人

Console.WriteLine(string.Format("A={0},B={1}", ZS.Age, SM.Age));

Console.ReadKey();

}

}

classPerson

{

publicint Age { get; set; }

}

相同的结构,不同的结果。

2.    何以证明string是引用类型

区分值类型与引用类型就是看它是值传递还是引用传递,如下:

using System;

classProgram

{

staticvoid Main()

{

int n = 99;

Console.WriteLine("Before:n={0}", n.GetHashCode());

//此时获取到的哈希码值就是n的变量值

GetInt(n);

string s = "Hello";

Console.WriteLine("Before:s={0}", s.GetHashCode());

GetString(s);

Console.ReadKey();

}

staticint GetInt(int n)

{

Console.WriteLine("After:m={0}", n.GetHashCode());

//传过来的是变量值,说明这是值传递

return n;

}

staticstring GetString(string s)

{

Console.WriteLine("After:s={0}", s.GetHashCode());

//传过来的是地址而不"Hello",说明这时引用传递

return s;

}

}

3.    string是特殊的引用类型

为什么说string是特殊的引用类型,因为看了下面的运行结果你会很困惑,这是怎么回事呢?且看代码分析:

classProgram

{

staticvoid Main()

{

string a = "Hello ";

Console.WriteLine(a.GetHashCode());

,指向对象的值为“Hello”。

string b = a;

Console.WriteLine(b.GetHashCode());

b = "world";

Console.WriteLine(b.GetHashCode());

//string类型的值三只读的,当给他重新赋值的时候需要额外分配内存,同时地址也发生变化。这也就是string类型和一般引用类型的不同之处

//可以这么理解,字符串变量吃饭用一次性碗筷,这也是为什么在做大量字符串拼接的时候要使用StringBuilder 而不用+=

Console.WriteLine("a:"+a+"\nb:"+b);

//此时有两个地址,分别对应托管堆上两个不同的对象值

Console.ReadKey();

}

}

运行结果:

请思考下面代码的运行结果:

staticvoid Main()

{

string s = "Hello!";

ChangeStr(s);//调用方法

Console.WriteLine(s);

}

staticvoid ChangeStr(string s){s = "你好!";}

答案:?

//ChangeStr方法体内传过来的确实是引用地址,但是由于string是只读的,给他重新赋值的时候又重新分配了新地址,而对原来地址和所对应的值没有影响

那怎么定义string的值传递方法呢?

staticstring ChangeStr(refstring s)

4.    string是一个变态类型

说string是特殊的引用类型是出于客气,写到这我就不能不破口大骂string是个变态狂了,Look:

classProgram

{

staticvoid Main()

{

string S1 = "Hello";

string S2 = "Hello";

bool r1 = object.ReferenceEquals(S1, S2);

var A = new { Age = 12 };   //对象A

var B = new { Age = 12 };   //对象B

bool r2 = object.ReferenceEquals(A, B);

Console.WriteLine("r1={0},r2={1}", r1, r2);

Console.ReadKey();

}

}

运行结果真的让人出乎意料,同样是引用类型,string总是和别人不一样。

消消气,理智一点分析,其实这就是string的内存驻留机制  ,也就是CLR为string做的优化(当有多个字符串变量包含了相同的值时, CLR尽可能不要重复地分配内存,而是让它们统统指向同一个字符串对象实例)。

staticvoid Main()

{

string p = "Hello";

string q = new StringBuilder().Append("Hello").ToString();

Console.WriteLine(object.ReferenceEquals(p, q));

//由于声明方式不同,所以CLR不会检查驻留池是否存在相同的变量值

Console.ReadKey();

}

staticvoid Main()

{

string p = "Hello";

string q = new StringBuilder().Append("Hello").ToString();

string o = string.Intern(q);  //强制CLR检查驻留池

Console.WriteLine(object.ReferenceEquals(p, o));

Console.ReadKey();

}

---- Author:Hollson     QQ:498576940

C#中的字符串的更多相关文章

  1. Python3中的字符串函数学习总结

    这篇文章主要介绍了Python3中的字符串函数学习总结,本文讲解了格式化类方法.查找 & 替换类方法.拆分 & 组合类方法等内容,需要的朋友可以参考下. Sequence Types ...

  2. 使用strings查看二进制文件中的字符串

    使用strings查看二进制文件中的字符串 今天介绍的这个小工具叫做strings,它实现功能很简单,就是找出文件内容中的可打印字符串.所谓可打印字符串的涵义是,它的组成部分都是可打印字符,并且以nu ...

  3. 在 case 语句中使用字符串-转

    http://www.cnblogs.com/del/archive/2008/07/08/1237856.html 非常遗憾 Delphi 的 case 语句不支持字符串, 但我觉得这也可能是基于效 ...

  4. 使用Microsoft Roslyn提取C#和VB.NET源代码中的字符串常量

    Microsoft Roslyn是微软.NET“编译器即服务(Compiler as a Service)”的主要产品,它提供了开放的编译器API,并为源代码产生.分析和重构提供了新一代的语言对象模型 ...

  5. SQL Server中截取字符串常用函数

    SQL Server 中截取字符串常用的函数: .LEFT ( character_expression , integer_expression ) 函数说明:LEFT ( '源字符串' , '要截 ...

  6. 在文件夹中 的指定类型文件中 查找字符串(CodeBlocks+GCC编译,控制台程序,仅能在Windows上运行)

    说明: 程序使用 io.h 中的 _findfirst 和 _findnext 函数遍历文件夹,故而程序只能在 Windows 下使用. 程序遍历当前文件夹,对其中的文件夹执行递归遍历.同时检查遍历到 ...

  7. 7.Java中的字符串

    1.String的特性 特性一:不可变性 String s=new String("yangyun") s=s.toUpperCase(); 这里的s,s占用的空间是不一样的(地址 ...

  8. C# 利用占位符替换word中的字符串和添加图片

    利用占位符替换word中的字符串和添加图片   ///<summary>         /// 替换word模板文件内容,包括表格中内容         /// 调用如下:WordStr ...

  9. 使用C#程序处理PowerPoint文件中的字符串

    最近, 有同事偶然发现Microsoft  Office PowerPoint可以被看作是一个压缩包,然后通过WinRAR解压出来一组XML文件.解压出来的文件包括: 一个索引文件名称为:[Conte ...

  10. Java OOP中的字符串篇

    字符串的三大特征: String 字符串常量 StringBuffer 字符串变量(线程安全) StringBuilder 字符串变量(非线程安全) 一.定义 查看 API 会发现,String.St ...

随机推荐

  1. [转] HDU 题目分类

    转载来自:http://www.cppblog.com/acronix/archive/2010/09/24/127536.aspx 分类一: 基础题:1000.1001.1004.1005.1008 ...

  2. matlab添加M_map工具箱(转 http://blog.sina.com.cn/s/blog_491b86bf0100srt9.html)

    之前转载过matlab画世界地图的博文.最近正好用到.首先试了matlab自带的worldmap,感觉画出来的图形不尽如人意,比较杂乱.如下图. 略查阅了些资料,请教了Liangjing,一致推荐m_ ...

  3. http://www.cnblogs.com/eye-like/p/4121219.html

    c# 操作Word总结 在医疗管理系统中为保存患者的体检和治疗记录,方便以后的医生或其他人查看.当把数据保存到数据库中,需要新建很多的字段,而且操作很繁琐,于是想到网页的信息创建到一个word文本中, ...

  4. 使用haproxy做负载均衡时保持客户端真实的IP

    haproxy里添加设置项 option forwardfor option httpclose apache的日志格式修改 LogFormat "MY IP=%{X-Forwarded-F ...

  5. python导入模块时的路径疑惑

    有一个事儿,以前没注意,今天发现了,记录一下. 假设一个python文件a.py中,有一段代码,是打印当前路径的.当单独执行a.py文件的时候,打印的是a.py的位置. 但是当a.py文件被其他pyt ...

  6. Eclipse 使用 Link 方式进行插件的安装

    Eclipse 使用 Link 方式进行插件的安装 博客分类: Eclipse 使用 eclipseplugin插件link  Eclipse 的插件安装方法一般有以下几种(以安装 SVN 插件为例说 ...

  7. 代码-Weka的LinearRegression类

    package kit.weka; import weka.classifiers.Evaluation; import weka.classifiers.functions.LinearRegres ...

  8. HW4.6

    public class Solution { public static void main(String[] args) { final double MILES_PER_KILOGRAM = 1 ...

  9. 树形遍历(java)---孩子双亲表示法

    给定一个树形结构,如图: 将它转换为孩子双亲表示法: 以下是JAVA实现://先序遍历 import java.util.ArrayList; public class TreeTraverse{ s ...

  10. glusterfs 术语

    Access Control Lists Access Control Lists (ACLs) allows you to assign different permissions for diff ...