码迷,mamicode.com
首页 > 其他好文 > 详细

值类型与引用类型

时间:2014-08-09 21:18:39      阅读:323      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   使用   os   strong   数据   

1.值类型
        C#的值类型包括:结构体(数值类型、bool型、用户定义的结构体),枚举,可空类型。
        Points是个结构体;给成员赋值有两种方式1.声明Points类型的对象,然后对象.成员分别赋值. 2.用new的方式初始化赋值,不会分配内存空间,此时要注意使用结构必须对每个成员进行赋值.但它是在栈空间中直接给成员分配内存,跟托管堆没有关系.
        执行Points ps2=ps1,这里是把ps1对象复制赋值给ps2,在栈中把x,y成员的值复制了一份给ps2,是复制并传递过程的一个概念.执行ps1.x=30,ps1改的是自己对象成员的值;跟ps2中的成员没有关系,所以ps2.x输出的是ps1初始化时的值10;而ps2.y是改变后的值40.

 1         static void Main(string[] args)//程序的入口方法
 2       {
 3           Points ps1;
 4           ps1.x = 10;
 5           ps1.y = 20;
 6           Points ps2 = ps1;
 7           ps1.x = 30;
 8           ps2.y = 40;
 9        }
10          struct Points //定义了一个结构Points
11        {
12           public int x; //结构成员x
13           public int y; //结构成员y
14        }

2.引用类型
       C#的引用类型包括:数组,用户定义的类、接口、委托,object,字符串。数组的元素,不管是引用类型还是值类型,都存储在托管堆上。引用类型在栈中存储一个引用,其实际的存储位置位于托管堆。
       Pointc是一个类;new一个对象pc1并且给对象成员初始化x=10,y=20,此时在堆中给对象分配内存给x,y并且产生一个引用地.对象pc1通过引用地址指向x,y对象pc1;在栈中存的是引用地址.执行Pointc pc2=pc1代码是把pc1对象的引用地址复制一份给pc2,对象pc2通过地址指向堆内存中的x,y成员.执行pc1.x=30代码,对象pc1通过地址修改x的值,pc2的地址也是指向堆中的成员,所以输出的值也是30.执行pc2.y=40代码也是通过原来的地址修改y的值,所以对象pc1,pc2修改后的值都是x=30,y=40.

 1         static void Main(string[] args)
 2         {
 3             MyPointc pc1 = new MyPointc();
 4             pc1.x = 10;
 5             pc1.y = 20;
 6             MyPointc pc2 = pc1;
 7             pc1.x=30;
 8             pc2.y=40;
 9         }
10        class MyPointc
11      {
12         public int x;
13         public int y;
14      }

bubuko.com,布布扣

值类型传参

 1         static void Main(string[] args)
 3         {
 5             Persons ps = new Persons();
 7             ps.state = "生病了";
 9             Docotr(ps);
11             Console.WriteLine(ps.state);
13             Console.ReadKey();
15         }
17          public static void Docotr(Persons p)
19         {
21             p.state = "病好了";
23         }
25          struct Persons
27         {
29 public string state; 31 }

结构Persons成员ps.state在栈在存放变量名,由于state是字符串所以存放的是堆中的引用地址,在堆中赋值分配空间。执行Docotr(ps);代码是把引用地址复制一份给Persons p

而指向原ps.state对象。当进入执行Docotr(Persons p)方法时,由于字符串不可改变性;在堆中会重新生成一个新的对象,从而p.state指向新的对象.

所以ps.state输出结果依然是“生病了

引用类型传参

 

 1        static void Main(string[] args)
 2         {
 3             Personc pc = new Personc();
 4             pc.state = "生病了";
 5             Docotr(pc);
 6             Console.WriteLine(pc.state);
 7             Console.ReadKey();
 8         }
 9          public static void Docotr( Personc p)
10         {
11             p.state = "病好了";
12         }
13          class Personc
14         {
15             public string state;
16         }

Personcnew一个对象pc在栈中存放引用地址,在堆中pc.state赋值并分配内存空间。Pc通过地址指向堆中成员.执行代码Docotr(pc);是把对象pc引用地址复制一份给对象p,

通过引用地址修改pc.state=病好了所以修改后的输出为病好了

bubuko.com,布布扣

值类型与引用类型传参补充:

bubuko.com,布布扣
         static void Main(string[] args)
        {
            Personc pc = new Personc();
            pc.state = "生病了";
            Docotr(pc.state);
            Console.WriteLine(pc.state);
            Console.ReadKey();
         }
          public static void Docotr(string str)
         {
            str = "病好了";
         }
         class Personc
         {
            public string state;
          }
View Code

引用类型复制的是地址,而数值类型复制的是值,但由于字符串的不可改变性,最终改变的都不是原来所指定的字符串对象,而是重新生成的新字符串,

所以对于引用类型还是数值类型来讲。用字符串参数传递都不会改变原字符串,所以上输出的结果为"生病了"

bubuko.com,布布扣

值类型直接存储其值,变量本身就包含了其实例数据,而引用类型保存的只是实例数据的内存引用。因此,一个值类型变量就永远不会影响到其他的值类型变量,

而两个引用类型变量则很有可能指向同一地址,从而发生相互影响。

引用类型与值类型相同的是,结构体也可以实现接口;引用类型可以派生出新的类型,而值类型不能;引用类型可以包含null值,值类型不能;

引用类型变量的赋值只复制对象的引用,而不复制对象本身。而将一个值类型变量赋给另一个值类型变量时,将复制包含的值。

 

值类型与引用类型,布布扣,bubuko.com

值类型与引用类型

标签:style   blog   http   color   使用   os   strong   数据   

原文地址:http://www.cnblogs.com/net-521/p/3901542.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!