分析C 分析称油价或出现回调
创始人
2024-06-08 16:50:52
0

在这里我们将介绍#中b=a的多种情况及结果,希望通过本文仔细做好两个变量中,一个改变而另一个的状态,希望对大家有所帮助。

本文旨在验证一个容易混淆的概念,从而为《玩转WPF/Silverlight中INotifyPropertyChanged和ObservableCollection》做铺垫。

两个相同类型的变量a和b,并且有如下关系:

b=a;

如果a发生改变,b是否也发生改变呢?

情况很复杂,分以下几种情况谈论:

1) 单个实体

1. 简单类型

先考察int:

  1. inta=1;
  2. intb=a;
  3. a=2;
  4. Console.WriteLine("b:"+b);
输出结果:

clip_image002

再考察一下string:

  1. stringa="1";
  2. stringb=a;
  3. a="2";
  4. Console.WriteLine("b:"+b);
输出结果:

输出结果

如果不放心,还可以测试一下Enum,结果类似,详见Demo。

结论:简单类型是组成复合类型的最基本单位,是原子,不可再拆分,所以不管是值类型double、int还是引用类型string,b都不随a的改变而改变,因为它们指向全局堆栈(对于string而言是托管堆)上的同一个地址。

2. 复合类型

复合类型是由string、int、double这些简单类型组成的。

分别定义一个复合的引用类型(class)和一个复合的值类型(struct)。

  1. classUserInfo
  2. {
  3. publicstringUserName;
  4. publicintAge;
  5. }
  6. structUserInfo2
  7. {
  8. publicstringUserName;
  9. publicintAge;
  10. }

先讨论引用类型:

  1. UserInfoa=newUserInfo(){UserName="Baobao",Age=27};
  2. UserInfob=a;
  3. a.UserName="AndersLiu";
  4. a.Age=30;
  5. Console.WriteLine("b.UserName:"+b.UserName);
  6. Console.WriteLine("b.Age:"+b.Age);
输出结果:

输出结果

结论:b和a仍然指向托管堆上的同一个UserInfo实例的地址。而UserInfo实例的成员又包含着UserName和Age分别在托管堆和全局堆栈上的地址。所以修改a的成员UserName和Age,只是改变这两个成员的地址,而没有改变UserInfo实例的地址,所以b的成员UserName和Age也会跟着改变。

让我们局部修改上面的代码:

  1. UserInfoa=newUserInfo(){UserName="Baobao",Age=27};
  2. UserInfob=a;
  3. //a.UserName="AndersLiu";
  4. //a.Age=30;
  5. a=newUserInfo(){UserName="AndersLiu",Age=30};
  6. Console.WriteLine("b.UserName:"+b.UserName);
  7. Console.WriteLine("b.Age:"+b.Age);
输出结果:

输出结果

结论:对a重新进行实例化,导致a指向一个新的UserInfo实例的地址。而b仍然指向原先那个UserInfo实例的地址,所以b不会随着a的改变而改变。从此b和a是两个没有任何关系的变量。

再来看一下值类型:

  1. UserInfo2a=newUserInfo2(){UserName="Baobao",Age=27};
  2. UserInfo2b=a;
  3. a.UserName="AndersLiu";
  4. a.Age=30;
  5. Console.WriteLine("b.UserName:"+b.UserName);
  6. Console.WriteLine("b.Age:"+b.Age);
输出结果:

另一种输出结果

结论:问题集中在b=a这句话上。这时b指向的是a的一份copy,指向全局堆栈上的与a不同的地址。所以b和a是没有任何关系的,b不随a的改变而改变。


2) 集合

1.集合中一笔数据的增删修改。

  1. Lista=newList();
  2. Listb=a;
  3. a.Add(newUserInfo(){UserName="Baobao",Age=27});
  4. Console.WriteLine("b.Countafteradding:"+b.Count);
  5. Console.WriteLine();
  6. Console.WriteLine("Aftermodifyinga[0]");
  7. a[0].UserName="AndersLiu";
  8. a[0].Age=30;
  9. Console.WriteLine("b[0].UserName:"+b[0].UserName);
  10. Console.WriteLine("b[0].Age:"+b[0].Age);
  11. Console.WriteLine();
  12. a.Remove(a[0]);
  13. Console.WriteLine("b.Countafterdeleting:"+b.Count);
输出结果:

输出结果

结论:b随着a中数据增减修改而变化。因为b和a指向托管堆上同一个List实例的内存地址,这和复合类型是一样的。

数组就不说了,可以看作是多个变量的集合,所以按照集合来处理。写了几段测试代码,放在Demo中。

原文标题:对于C#中b=a的N种情况分析

链接:http://www.cnblogs.com/Jax/archive/2009/10/12/1581725.html

【编辑推荐】

  1. C#数组基础介绍与操作详解
  2. 浅析C#数组初始化性能测试
  3. C#数组操作详细剖析
  4. 浅析C#数组操作方法
  5. C#数组和串操作经验总结

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...
《非诚勿扰》红人闫凤娇被曝厕所... 【51CTO.com 综合消息360安全专家提醒说,“闫凤娇”、“非诚勿扰”已经被黑客盯上成为了“木...
2012年第四季度互联网状况报... [[71653]]  北京时间4月25日消息,据国外媒体报道,全球知名的云平台公司Akamai Te...