string a = "aaaa";
string b = a;
a = "bbbb";
Console.WriteLine(b);
//输出 aaaa
int[] A = {1,2,3};
int[] B = A;
A[0] = 4;
Console.WriteLine(B[0]);
//输出 4
我的理解是:string也是引用类型为什么结果会不一样呢?就解答。
直接上代码:
1 namespace String 2 { 3 class Program 4 { 5 static void Main(string[] args) 6 { 7 StringDemo(); 8 RefClassDemo(); 9 //上面的这个两个例子string和普通的引用类型是一样的 10 //----------------------- 11 12 13 //下面说明为什么有个类似你疑问的”假象“ 14 RefClassDemo2(); 15 //string的”不可变“属性(immutable)指的是,string不提供如何可以改变其自身的方法(类似于DemoRefClass的ChangeDemoField这样子的方法) 16 Console.Read(); 17 } 18 19 private static void StringDemo() 20 { 21 string a = "a1";//相当于new string() 22 string b = a;//这个时候b指向了a的引用。 23 Console.WriteLine(a);//a1 24 Console.WriteLine(b);//a1 25 b = "a2";//相当于new string()。b重新分配了内存,和a的引用断开了。 26 Console.WriteLine(a);//a1 27 Console.WriteLine(b);//a2,因为new 重新分配,so改变 28 29 } 30 31 private static void RefClassDemo() 32 { 33 var a = new DemoRefClass(10); 34 var b = a;//这个时候b指向了a的引用。 35 Console.WriteLine(a);//10 36 Console.WriteLine(b);//10 37 b = new DemoRefClass(20);//重新new,b重新分配了内存,和a的引用断开了。 38 Console.WriteLine(a);//10 39 Console.WriteLine(b);//20,和String是一样的,都改变了。因为用了new,重新分配了内存 40 } 41 42 private static void RefClassDemo2() 43 { 44 var a = new DemoRefClass(10); 45 var b = a;//这个时候b指向了a的引用。 46 Console.WriteLine(a);//10 47 Console.WriteLine(b);//10 48 b.ChangeDemoField(30);//这个时候b和a还是指向同一块内存,没有new,so改变一个,两个全部改变 49 Console.WriteLine(a);//30 50 Console.WriteLine(b);//30 51 } 52 } 53 54 public class DemoRefClass 55 { 56 private int demoField; 57 public DemoRefClass(int initialValue) 58 { 59 this.demoField = initialValue; 60 } 61 public void ChangeDemoField(int newValue) 62 { 63 this.demoField = newValue; 64 } 65 public override string ToString() 66 { 67 return this.demoField.ToString(); 68 } 69 } 70 }
int[] A = {1,2,3}; int[] B = A; A[0] = 4; Console.WriteLine(B[0]);
这段代码里面int[] 提供了“改变自身的方法”。A[0] = 4;
我的理解是: string a ="aaaa"; 这个操作是 为 "aaaa" 分配了一个内存空间。 string a 是申明了一个引用(也叫地址)。然后指向"aaaa"值内存空间。
string b = a; 是申请了一个新引用b(也叫地址),他和a一样,同样指向"aaaa"的内在空间。
a= "bbbb" 则是将所申明的a引用引向了 “bbbb”的内存。 其实这个时候"aaaa"还在内存,而且b的引用是指向"aaaa"的。所以输出的是aaaa
有道理,是不是由于string的恒定性这个特点导致的呢?
@|WinKi|: 嗯,这只是我的理解。
虽然string的引用类型,不过每一个string,会申请一个独立的内存空间。
1. a = "bbbb"; //a的引用改变了
a、b是不同的引用地址
2. A[0] = 4; //A[0]的引用改变
A 和B的引用是一样的,未改变,堆栈中未变,指向的托管堆中再怎么变,都是一样的。
跟 字符串驻留没关系, 可以 看看 内存分配
给一个String类型变量重新赋值时,会在内存中重新开辟一块空间存放新值,然后将新值的引用赋给该String型变量。在有大量字符串拼接时,不建议使用String类型的原因也在于此。具体可见园子里的这篇帖子