C#对象赋值出现的诡异问题,或许你也遇到过,有待你的解决
2015-07-31 14:09
232 查看
前言:今天在代码中,又出现了这个问题,就是对象赋值给一个新的对象时,然后更改新对象中的属性,就会把老对象的值也更改,以前也遇到这个问题,只是没有深究,今天刚好又遇到了此问题,我决定写下来,和大家一起分享,也同样希望大家给出更加合理的解决方案,和原理。 |
int j; j = 1; int k; k = j; k = 2; 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
下面是一个控制台输出代码,这段代码也就是总体来说,就是一个赋值的问题:
class Program { static void Main(string[] args) { // 订单 var objOrderInfo = new OrderInfo() { OrderNO = "201507310001" }; // 订单明细 OrderDetaileInfo objOrderDetaileInfo = null; for (int i = 1; i < 5; i++) { objOrderDetaileInfo = new OrderDetaileInfo() { OrderNO = objOrderInfo.OrderNO, Number = i, Price = i * 5, ProductName = "三星SSD-" + i }; objOrderInfo.OrderDetaileInfo.Add(objOrderDetaileInfo); } string str = null; Console.WriteLine("-------------------首次循环OrderDetaileInfo开始--------------------\n"); objOrderInfo.OrderDetaileInfo.ForEach(t => { str = string.Format("订单号:{0}\n商品名称:{1}\n数量:{2}\n单价:{3}\n总计:{4}\n", t.OrderNO, t.ProductName, t.Number, t.Price.ToString("C"), t.Total); Console.WriteLine(str); }); Console.WriteLine("订单总金额:" + objOrderInfo.OrderAmount.ToString("C")); Console.WriteLine("-------------------首次循环OrderDetaileInfo结束--------------------"); OrderInfo objOrderInfo2 = new OrderInfo() { OrderNO = "201507310002" }; OrderDetaileInfo objOrderDetaileInfo2 = null; int num = 5; foreach (var item in objOrderInfo.OrderDetaileInfo) { objOrderDetaileInfo2 = new OrderDetaileInfo(); objOrderDetaileInfo2 = item; objOrderDetaileInfo2.OrderNO = objOrderInfo2.OrderNO; objOrderDetaileInfo2.Number = num; num++; objOrderInfo2.OrderDetaileInfo.Add(objOrderDetaileInfo2); } Console.WriteLine("-------------------重新把OrderDetaileInfo赋值给OrderDetaileInfo2开始---------\n"); objOrderInfo2.OrderDetaileInfo.ForEach(t => { str = string.Format("订单号:{0}\n商品名称:{1}\n数量:{2}\n单价:{3}\n总计:{4}\n", t.OrderNO, t.ProductName, t.Number, t.Price.ToString("C"), t.Total); Console.WriteLine(str); }); Console.WriteLine("订单总金额:" + objOrderInfo2.OrderAmount.ToString("C")); Console.WriteLine("-------------------重新把OrderDetaileInfo赋值给OrderDetaileInfo2结束---------"); // 当把OrderDetaileInfo赋值给OrderDetaileInfo2后,竟然把OrderDetaileInfo对象变为了OrderDetaileInfo2 Console.WriteLine("-------------------再次循环OrderDetaileInfo开始--------------------\n"); objOrderInfo.OrderDetaileInfo.ForEach(t => { str = string.Format("订单号:{0}\n商品名称:{1}\n数量:{2}\n单价:{3}\n总计:{4}\n", t.OrderNO, t.ProductName, t.Number, t.Price.ToString("C"), t.Total); Console.WriteLine(str); }); Console.WriteLine("订单总金额:" + objOrderInfo.OrderAmount.ToString("C")); Console.WriteLine("-------------------再次循环OrderDetaileInfo结束--------------------"); Console.ReadLine(); } }
这段代码不难看懂,第一次输出的是订单信息,第二次输出的是把第一次的订单明细赋值给第二次订单的明细,然后改变第二次订单明细是商品的数量(看红色代码),第三次输出的是第一次的订单信息,按照前面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楼,多谢大家的帮助
相关文章推荐
- C# 反射
- C# + emgucv显示实时视频并检测人脸
- C# StructLayouAttribute属性
- C#_Stopwatch 类
- C# List的排序问题
- c#读取XML
- C#中的Finalize,Dispose,SuppressFinalize的实现和使用介绍
- C#中标准Dispose模式的实现
- 关于C# DATAGRIDVIEW select 后绑定数据源顺序混乱的问题
- [转]C#4.0中的协变和逆变
- C# Socket编程笔记
- C# 扩展方法
- C#6.0语法糖剖析(一)
- C# 注册COM+组件步骤~
- C# Serializable
- C#中操作xml文件(插入节点、修改、删除)
- C# Thread类的应用
- C# 委托的同步调用和异步调用
- C# txt文本读取最后X行
- C#自定义log机制