C#對象賦值出現的詭異問題,或許你也遇到過,有待你的解決


前言:今天在代碼中,又出現了這個問題,就是對象賦值給一個新的對象時,然后更改新對象中的屬性,就會把老對象的值也更改,以前也遇到這個問題,只是沒有深究,今天剛好又遇到了此問題,我決定寫下來,和大家一起分享,也同樣希望大家給出更加合理的解決方案,和原理。

通過這個簡單的例子引出我所出現的問題:

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; } }
    }
}
View Code

 

下面是一個控制台輸出代碼,這段代碼也就是總體來說,就是一個賦值的問題:

 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傳上來,供大家測試,下載地址

 

解決方案看:#16樓 #18樓 #27樓,多謝大家的幫助


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM