公司网站建设费分录,简答题网络营销是什么,视频网站中滑动列表怎么做的,顺义专业建站公司你真的了解.NET中的String吗? Terrylee#xff0c;2005年12月25日 概述 String在任何语言中#xff0c;都有它的特殊性#xff0c;在.NET中也是如此。它属于基本数据类型#xff0c;也是基本数据类型中唯一的引用类型。字符串可以声明为常量#xff0c;但是它却放在了堆中…你真的了解.NET中的String吗? Terrylee2005年12月25日 概述 String在任何语言中都有它的特殊性在.NET中也是如此。它属于基本数据类型也是基本数据类型中唯一的引用类型。字符串可以声明为常量但是它却放在了堆中。希望通过本文能够使大家对.NET中的String有一个深入的了解。 不可改变对象 在.NET中String是不可改变对象一旦创建了一个String对象并为它赋值它就不可能再改变也就是你不可能改变一个字符串的值。这句话初听起来似乎有些不可思议大家也许马上会想到字符串的连接操作我们不也可以改变字符串吗看下面这段代码 1using System; 2 3namespace Demo1 4{ 5 /**summary 6 /// String连接测试 7 /// /summary 8 public class Test 9 { 10 public static void Main(string[] args) 11 { 12 string a 1234; 13 Console.WriteLine(a); 14 15 a 5678; 16 Console.WriteLine(a); 17 Console.ReadLine(); 18 } 19 } 20} 21 运行的结果 1234 12345678 看起来我们似乎已经把MyStr的值从“1234”改为了“12345678”。事实是这样的吗实际上并没有改变。在第5行代码中创建了一个String对象它的值是“1234”MyStr指向了它在内存中的地址第七行代码中创建了一个新的String对象它的值是“12345678”MyStr指向了新的内存地址。这时在堆中其实存在着两个字符串对象尽管我们只引用了它们中的一个但是字符串“1234”仍然在内存中驻留。 引用类型 前面说过String是引用类型这就是如果我们创建很多个相同值的字符串对象它在内存中的指向地址应该是一样的。也就是说当我们创建了字符串对象a它的值是“1234”当我们再创建一个值为“1234”的字符串对象b时它不会再去分配一块内存空间而是直接指向了a在内存中的地址。这样可以确保内存的有效利用。看下面的代码 1using System; 2 3namespace Demo2 4{ 5 /**summary 6 /// String引用类型测试 7 /// /summary 8 public class Test 9 { 10 public static void Main(string[] args) 11 { 12 string a 1234; 13 14 Console.WriteLine(a); 15 16 Test.Change(a); 17 18 Console.WriteLine(a); 19 Console.ReadLine(); 20 } 21 22 public static void Change(string s) 23 { 24 s 5678; 25 } 26 } 27} 运行结果 1234 1234 做一个小改动注意Change(ref string s) 1using System; 2 3namespace Demo2 4{ 5 /** summary 6 /// String引用类型测试 7 /// /summary 8 public class Test 9 { 10 public static void Main(string[] args) 11 { 12 string a 1234; 13 14 Console.WriteLine(a); 15 16 Test.Change(ref a); 17 18 Console.WriteLine(a); 19 Console.ReadLine(); 20 } 21 22 public static void Change(ref string s) 23 { 24 s 5678; 25 } 26 } 27} 28 运行结果 1234 5678 字符串的比较 在.NET中对字符串的比较操作并不仅仅是简单的比较二者的值 操作首先比较两个字符串的引用如果引用相同就直接返回True如果不同再去比较它们的值。所以如果两个值相同的字符串的比较相对于引用相同的字符串的比较要慢中间多了一步判断引用是否相同。看下面这段代码 1using System; 2 3namespace Demo3 4{ 5 /** summary 6 /// String类型的比较 7 /// /summary 8 public class Test 9 { 10 public static void Main(string[] args) 11 { 12 string a 1234; 13 string b 1234; 14 string c 123; 15 c 4; 16 17 int times 1000000000; 18 int start,end; 19 20 /**测试引用相同所用的实际时间 21 start Environment.TickCount; 22 for(int i0;itimes;i) 23 { 24 if(ab) 25 {} 26 } 27 end Environment.TickCount; 28 Console.WriteLine((end-start)); 29 30 /**测试引用不同而值相同所用的实际时间 31 start Environment.TickCount; 32 for(int i0;itimes;i) 33 { 34 if(ac) 35 {} 36 } 37 end Environment.TickCount; 38 Console.WriteLine((end-start)); 39 40 Console.ReadLine(); 41 } 42 } 43} 44 执行的结果运行的结果可能有些不同 1671 4172 由此我们看出值相同时的比较用 比引用相同时的比较慢了好多。这里仅仅是一个测试因为做这样的比较并没有任何实际的意义。有一点需要明确的是.NET中跟Equals()内部机制完全是一样的是它的一个重载。 1public static bool operator (string a, string b) 2{ 3 return string.Equals(a, b); 4} 5 1public static bool Equals(string a, string b) 2{ 3 if (a b) 4 { 5 return true; 6 } 7 if ((a ! null) (b ! null)) 8 { 9 return a.Equals(b); 10 } 11 return false; 12} 13 字符串驻留 看一下这段代码 1using System; 2 3namespace Demo4 4{ 5 /**summary 6 /// String的驻留 7 /// /summary 8 public class Test 9 { 10 public static void Main(string[] args) 11 { 12 string a 1234; 13 string s 123; 14 s 4; 15 16 string b s; 17 string c String.Intern(s); 18 19 Console.WriteLine((object)a (object)b); 20 Console.WriteLine((object)a (object)c); 21 Console.ReadLine(); 22 } 23 } 24} 25 执行的结果 False True 在这段代码中比较这两个对象发现它的引用并不是一样的。如果要想是它们的引用相同可以用Intern()函数来进行字符串的驻留如果有这样的值存在。 StringBuilder对象 通过上面的分析可以看出String类型在做字符串的连接操作时效率是相当低的并且由于每做一个连接操作都会在内存中创建一个新的对象占用了大量的内存空间。这样就引出StringBuilder对象StringBuilder对象在做字符串连接操作时是在原来的字符串上进行修改改善了性能。这一点我们平时使用中也许都知道连接操作频繁的时候使用StringBuilder对象。但是这两者之间的差别到底有多大呢来做一个测试 1using System; 2using System.Text; 3 4namespace Demo5 5{ 6 /**summary 7 /// String和StringBulider比较 8 /// /summary 9 public class Test 10 { 11 public static void Main(string[] args) 12 { 13 string a ; 14 StringBuilder s new StringBuilder(); 15 16 int times 10000; 17 int start,end; 18 19 /**测试String所用的时间 20 start Environment.TickCount; 21 for(int i0;itimes;i) 22 { 23 a i.ToString(); 24 } 25 end Environment.TickCount; 26 Console.WriteLine((end-start)); 27 28 /**测试StringBuilder所用的时间 29 start Environment.TickCount; 30 for(int i0;itimes;i) 31 { 32 s.Append(i.ToString()); 33 } 34 end Environment.TickCount; 35 Console.WriteLine((end-start)); 36 37 Console.ReadLine(); 38 } 39 } 40} 41 运行结果 884 0 通过上面的分析可以看出用String来做字符串的连接时效率非常低但并不是所任何情况下都要用StringBuilder当我们连接很少的字符串时可以用String但当做大量的或频繁的字符串连接操作时就一定要用StringBuilder。 作者TerryLee出处http://terrylee.cnblogs.com/ 转载于:https://www.cnblogs.com/SunWentao/archive/2008/04/21/1164193.html