参考: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用新的对象替代了原来的对象。
总结完毕。