首页 新闻 会员 周边

关于数据类型

0
悬赏园豆:10 [已解决问题] 解决于 2013-08-13 09:21

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也是引用类型为什么结果会不一样呢?就解答。

|WinKi|的主页 |WinKi| | 小虾三级 | 园豆:669
提问于:2013-08-12 16:39
< >
分享
最佳答案
1

直接上代码:

 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 }
收获园豆:6
小AI | 菜鸟二级 |园豆:354 | 2013-08-12 19:55
int[] A = {1,2,3};
int[] B = A;
A[0] = 4;
Console.WriteLine(B[0]);

这段代码里面int[] 提供了“改变自身的方法”。A[0] = 4;

小AI | 园豆:354 (菜鸟二级) | 2013-08-12 19:59
其他回答(4)
1

我的理解是:  string a ="aaaa"; 这个操作是 为 "aaaa" 分配了一个内存空间。  string a 是申明了一个引用(也叫地址)。然后指向"aaaa"值内存空间。 

string b = a; 是申请了一个新引用b(也叫地址),他和a一样,同样指向"aaaa"的内在空间。

a= "bbbb" 则是将所申明的a引用引向了 “bbbb”的内存。  其实这个时候"aaaa"还在内存,而且b的引用是指向"aaaa"的。所以输出的是aaaa

收获园豆:2
jerry-Tom | 园豆:4077 (老鸟四级) | 2013-08-12 16:49

有道理,是不是由于string的恒定性这个特点导致的呢?

支持(0) 反对(0) |WinKi| | 园豆:669 (小虾三级) | 2013-08-12 17:13

@|WinKi|: 嗯,这只是我的理解。

支持(0) 反对(0) jerry-Tom | 园豆:4077 (老鸟四级) | 2013-08-12 17:20
0

虽然string的引用类型,不过每一个string,会申请一个独立的内存空间。

幻天芒 | 园豆:37175 (高人七级) | 2013-08-12 18:34
1

1. a = "bbbb";  //a的引用改变了

     a、b是不同的引用地址

2.  A[0] = 4;  //A[0]的引用改变

A 和B的引用是一样的,未改变,堆栈中未变,指向的托管堆中再怎么变,都是一样的。

跟 字符串驻留没关系, 可以 看看 内存分配

收获园豆:2
Qlin | 园豆:2403 (老鸟四级) | 2013-08-12 19:00
0

给一个String类型变量重新赋值时,会在内存中重新开辟一块空间存放新值,然后将新值的引用赋给该String型变量。在有大量字符串拼接时,不建议使用String类型的原因也在于此。具体可见园子里的这篇帖子

nianhua11 | 园豆:736 (小虾三级) | 2013-08-12 19:46
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册