• 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开始--------------------
    ");
    26             objOrderInfo.OrderDetaileInfo.ForEach(t =>
    27             {
    28                 str = string.Format("订单号:{0}
    商品名称:{1}
    数量:{2}
    单价:{3}
    总计:{4}
    ",
    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开始---------
    ");
    51             objOrderInfo2.OrderDetaileInfo.ForEach(t =>
    52             {
    53                 str = string.Format("订单号:{0}
    商品名称:{1}
    数量:{2}
    单价:{3}
    总计:{4}
    ",
    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开始--------------------
    ");
    63             objOrderInfo.OrderDetaileInfo.ForEach(t =>
    64             {
    65                 str = string.Format("订单号:{0}
    商品名称:{1}
    数量:{2}
    单价:{3}
    总计:{4}
    ",
    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楼,多谢大家的帮助

  • 相关阅读:
    手动创建分区以及软硬raid的问题
    实用小工具:VNC的安装
    安装使用xen虚拟化工具
    使用vsftp与shell实现对进程与服务状态的监控
    windows server2008下搭建ftp服务
    业界虚拟化技术分析
    Android命名规范(自定义)
    Android Paint和Color类
    Android 应用中十大常见 UX 错误
    漫谈互联网产品设计之人性的弱点,你躺枪了木有?
  • 原文地址:https://www.cnblogs.com/luxianai/p/net_assignment.html
Copyright © 2020-2023  润新知