2
3 namespace 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 i=0;i<times;i++)
23 ...{
24 if(a==b)
25 ...{}
26 }
27 end = Environment.TickCount;
28 Console.WriteLine((end-start));
29
30 /**////测试引用不同而值相同所用的实际时间
31 start = Environment.TickCount;
32 for(int i=0;i<times;i++)
33 ...{
34 if(a==c)
35 ...{}
36 }
37 end = Environment.TickCount;
38 Console.WriteLine((end-start));
39
40 Console.ReadLine();
41 }
42 }
43 }
有一点需要明确的是, .NET 中 == 跟 Equals() 内部机制完全是一样的, == 是它的一个重载。
2 ... {
3 return string.Equals(a, b);
4 }
5
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 }
2
3 namespace 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 }
2 using System.Text;
3
4 namespace 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 i=0;i<times;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 i=0;i<times;i++)
31 ...{
32 s.Append(i.ToString());
33 }
34 end = Environment.TickCount;
35 Console.WriteLine((end-start));
36
37 Console.ReadLine();
38 }
39 }
40 }
2
3 namespace 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 }
运行的结果:
1234
12345678
看起来我们似乎已经把MyStr的值从“1234”改为了“12345678”。事实是这样的吗?实际上并没有改变。在第5行代码中创建了一个String对象它的值是“1234”,MyStr指向了它在内存中的地址;第七行代码中创建了一个新的String对象它的值是“12345678”,MyStr指向了新的内存地址。这时在堆中其实存在着两个字符串对象,尽管我们只引用了它们中的一个,但是字符串“1234”仍然在内存中驻留。
引用类型
前面说过String是引用类型,这就是如果我们创建很多个相同值的字符串对象,它在内存中的指向地址应该是一样的。也就是说,当我们创建了字符串对象a,它的值是“1234”,当我们再创建一个值为“1234”的字符串对象b时它不会再去分配一块内存空间,而是直接指向了a在内存中的地址。这样可以确保内存的有效利用。看下面的代码:
1
using System;
2
3
namespace 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)
2
3 namespace 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