SherryW

导航

有关C# struct的一个误区

参考:http://blog.csdn.net/onlyou930/article/details/5568319

下面写一个新的例子:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Data.SQLite;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7 
 8 namespace ConsoleApplication1
 9 {
10     public struct Rectangle
11     {
12         private int height;
13         public int Height
14         {
15             get { return height; }
16             set { height = value; }
17         }
18 
19         private int width;
20         public int Width
21         {
22             get { return width; }
23             set { width = value; }
24         }
25 
26         public Rectangle(int a,int b)
27         {
28             height = a;
29             width = b;
30         }
31     }
32        
33     class Program
34     {
35         static void Main(string[] args)
36         {
37             List<Rectangle> rectangle = new List<Rectangle>() { new Rectangle() };
38             rectangle[0].Height = 20;
39             rectangle[0].Width = 30;
40         }
41 
42        
43     }
44 }

代码写完之后,有代码有错误:

编译生成后“错误列表”中显示:

出现这个问题的原因分析:

在以上代码中,rectangle是引用类型,rectangle的对象在堆上,虽然rectangle[0]是值类型,但它是rectangle的组成部分,仍然在堆上,而值类型默认是按值传递,所以将rectangle[0]的值做临时的拷贝到栈上,我们暂且称之为temp_rectangle[0],

temp_rectangle[0].Height=20;

temp_rectangle[0]的值是变了,但是rectangle[0]的值并不会改变,所以上面错误代码中的赋值操作是没有意义的,故编译器直接不让编译通过。

在实际中,我们通常似乎需要完成类似的功能,那怎么办呢?有两种解决途径,1)将struct改成class,class是引用类型,就不存在值传递的问题了;2)做一个对象替换,具体代码如下:

 1  class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             //List<Rectangle> rectangle = new List<Rectangle>() { new Rectangle() };
 6             var rectangle = new Rectangle();
 7             rectangle.Height = 20;
 8             rectangle.Width = 30;
 9             List<Rectangle> listRectangle = new List<Rectangle>() { rectangle};
10         }   
11     }

Height和Width的值如下:

解决方案2用新的对象替代了原来的对象。

总结完毕。

 

 

posted on 2014-03-03 17:28  SherryW  阅读(1311)  评论(0编辑  收藏  举报