前言:今天在代碼中,又出現了這個問題,就是對象賦值給一個新的對象時,然后更改新對象中的屬性,就會把老對象的值也更改,以前也遇到這個問題,只是沒有深究,今天剛好又遇到了此問題,我決定寫下來,和大家一起分享,也同樣希望大家給出更加合理的解決方案,和原理。 |
通過這個簡單的例子引出我所出現的問題:
1 int j; 2 j = 1; 3 4 int k; 5 k = j; 6 7 k = 2; 8 9 Console.WriteLine(string.Format("i={0},k={1}", j, k));
代碼很簡單,輸出的結果也很容易看出來,結果當然輸入的是:i=1,k=2
這樣的輸出結果當然無需置疑,那么我們現在按照這個邏輯進入下面的代碼,結果除非人的意料。
首先是一個實體對象類:

namespace ConsoleApplication { /// <summary> /// 訂單 /// </summary> public class OrderInfo { public OrderInfo() { this.OrderDetaileInfo = new List<OrderDetaileInfo>(); } /// <summary> /// 訂單號 /// </summary> public string OrderNO { get; set; } /// <summary> /// 訂單總金額 /// </summary> public decimal OrderAmount { get { return this.OrderDetaileInfo == null ? 0 : this.OrderDetaileInfo.Sum(t => t.Total); } } /// <summary> /// 訂單明細 /// </summary> public List<OrderDetaileInfo> OrderDetaileInfo { get; set; } } /// <summary> /// 訂單明細 /// </summary> public class OrderDetaileInfo { /// <summary> /// 訂單號 /// </summary> public string OrderNO { get; set; } /// <summary> /// 商品名稱 /// </summary> public string ProductName { get; set; } /// <summary> /// 商品數量 /// </summary> public int Number { get; set; } /// <summary> /// 商品單價 /// </summary> public decimal Price { get; set; } /// <summary> /// 總價 /// </summary> public decimal Total { get { return this.Price * this.Number; } } } }
下面是一個控制台輸出代碼,這段代碼也就是總體來說,就是一個賦值的問題:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 // 訂單 6 var objOrderInfo = new OrderInfo() 7 { 8 OrderNO = "201507310001" 9 }; 10 11 // 訂單明細 12 OrderDetaileInfo objOrderDetaileInfo = null; 13 for (int i = 1; i < 5; i++) 14 { 15 objOrderDetaileInfo = new OrderDetaileInfo() 16 { 17 OrderNO = objOrderInfo.OrderNO, 18 Number = i, 19 Price = i * 5, 20 ProductName = "三星SSD-" + i 21 }; 22 objOrderInfo.OrderDetaileInfo.Add(objOrderDetaileInfo); 23 } 24 string str = null; 25 Console.WriteLine("-------------------首次循環OrderDetaileInfo開始--------------------\n"); 26 objOrderInfo.OrderDetaileInfo.ForEach(t => 27 { 28 str = string.Format("訂單號:{0}\n商品名稱:{1}\n數量:{2}\n單價:{3}\n總計:{4}\n", 29 t.OrderNO, t.ProductName, t.Number, t.Price.ToString("C"), t.Total); 30 Console.WriteLine(str); 31 }); 32 Console.WriteLine("訂單總金額:" + objOrderInfo.OrderAmount.ToString("C")); 33 Console.WriteLine("-------------------首次循環OrderDetaileInfo結束--------------------"); 34 35 OrderInfo objOrderInfo2 = new OrderInfo() 36 { 37 OrderNO = "201507310002" 38 }; 39 OrderDetaileInfo objOrderDetaileInfo2 = null; 40 int num = 5; 41 foreach (var item in objOrderInfo.OrderDetaileInfo) 42 { 43 objOrderDetaileInfo2 = new OrderDetaileInfo(); 44 objOrderDetaileInfo2 = item; 45 objOrderDetaileInfo2.OrderNO = objOrderInfo2.OrderNO; 46 objOrderDetaileInfo2.Number = num; 47 num++; 48 objOrderInfo2.OrderDetaileInfo.Add(objOrderDetaileInfo2); 49 } 50 Console.WriteLine("-------------------重新把OrderDetaileInfo賦值給OrderDetaileInfo2開始---------\n"); 51 objOrderInfo2.OrderDetaileInfo.ForEach(t => 52 { 53 str = string.Format("訂單號:{0}\n商品名稱:{1}\n數量:{2}\n單價:{3}\n總計:{4}\n", 54 t.OrderNO, t.ProductName, t.Number, t.Price.ToString("C"), t.Total); 55 Console.WriteLine(str); 56 }); 57 Console.WriteLine("訂單總金額:" + objOrderInfo2.OrderAmount.ToString("C")); 58 Console.WriteLine("-------------------重新把OrderDetaileInfo賦值給OrderDetaileInfo2結束---------"); 59 60 // 當把OrderDetaileInfo賦值給OrderDetaileInfo2后,竟然把OrderDetaileInfo對象變為了OrderDetaileInfo2 61 62 Console.WriteLine("-------------------再次循環OrderDetaileInfo開始--------------------\n"); 63 objOrderInfo.OrderDetaileInfo.ForEach(t => 64 { 65 str = string.Format("訂單號:{0}\n商品名稱:{1}\n數量:{2}\n單價:{3}\n總計:{4}\n", 66 t.OrderNO, t.ProductName, t.Number, t.Price.ToString("C"), t.Total); 67 Console.WriteLine(str); 68 }); 69 Console.WriteLine("訂單總金額:" + objOrderInfo.OrderAmount.ToString("C")); 70 Console.WriteLine("-------------------再次循環OrderDetaileInfo結束--------------------"); 71 72 Console.ReadLine(); 73 } 74 }
這段代碼不難看懂,第一次輸出的是訂單信息,第二次輸出的是把第一次的訂單明細賦值給第二次訂單的明細,然后改變第二次訂單明細是商品的數量(看紅色代碼),第三次輸出的是第一次的訂單信息,按照前面j和k的代碼,第三次輸出的應該和第一次輸出的結果一值,BUT,看圖:
第一次輸出的結果:
第二次輸出的結果:
第三次的輸出結果(按照J,K的例子,第三次的和第一次的應該一樣,可惜啊)LOOK
可惜第三次並不是和第一次一樣,而是和第二次輸出的訂單明細一樣。
沒辦法只能把紅色的代碼改成這樣,才能正確
foreach (var item in objOrderInfo.OrderDetaileInfo) { objOrderDetaileInfo2 = new OrderDetaileInfo(); //objOrderDetaileInfo2 = item; objOrderDetaileInfo2.OrderNO = objOrderInfo2.OrderNO; objOrderDetaileInfo2.ProductName = item.ProductName; objOrderDetaileInfo2.Price = item.Price; objOrderDetaileInfo2.Number = num; num++; objOrderInfo2.OrderDetaileInfo.Add(objOrderDetaileInfo2); }
具體解決辦法只能這樣,不知道哪位大牛更改幫忙講解一下,或者有更好的解決辦法,因為字段多了,一個一個賦值太麻煩。
隨便把DEMO傳上來,供大家測試,下載地址