c# - 对象得到更新,它作为参数传递给 c# 中的方法
问题描述
我今天在我的应用程序中观察到一个奇怪的行为。我的数据访问层中有以下方法之一:
public async Task<Order> WriteOrder(Order orderDetails)
{
try
{
Order updatedOrder = GenerateOrderID(orderDetails);
Task insertOrder = orderCollection.InsertOneAsync(orderDetails); // updatedOrder was supposed to be passed here.
// inserts values into Database.
}
}
private Order GenerateOrderID(Order order)
{
try
{
order.Id = Guid.NewGuid().ToString();
order.SubmittedOn = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss");
return order;
}
catch(Exception ex)
{
throw;
}
}
public class Order
{
[DataMember(Name = "id")]
public string Id { get; set; }
[DataMember(Name = "submittedOn")]
public string SubmittedOn { get; set; }
// some other Data Memebers
}
说明:
WriteOrder
方法orderDetails
作为输入参数接收,然后我将其传递给GeneratedOrderId
方法,其中 Id 和其他一些细节被更新并返回订单对象。我们正在接收对象中的updatedOrder
对象(我们没有在任何地方使用)。然后将orderdetails
对象传递给InsertOneAsync
方法并插入数据库。
一直以来我都没有注意到它,但我应该updatedOrder
作为参数传递给InsertOneAsync
方法,而不是orderDetails
.
但不知何故,它正在工作,即在数据库中更新的 ID 和SubmittedOn
详细信息。当我调试和看到时,orderDetails
对象也得到更新(据我说不应该)。为什么以及如何发生这种情况?
解决方案
这里要理解的基本内容是,当我们将引用类型的对象传递给方法时,引用是按值传递的。在您的代码中,没有创建新对象的位置Order
。
因此,无论您在何处更改属性值,都会更新同一对象的状态。内存中只有一个对象,并且您有指向相同引用的不同副本。
这意味着在以下方法调用中:
private Order GenerateOrderID(Order order)
该变量持有与调用者端order
指向的相同对象。orderDetails
两个引用副本,但指向内存中的同一个对象。
Order
如果您在私有方法中创建新对象,则方法中的微小变化将完全改变行为。然后你会看到传递的对象没有得到更新。看:
private Order GenerateOrderID(Order order)
{
try
{
order = new Order(); // note this line
order.Id = Guid.NewGuid().ToString();
order.SubmittedOn = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss");
return order;
}
catch(Exception ex)
{
throw;
}
}
现在我们有一个新对象,我们设置它的状态。现在updatedOrder
andorderDetails
都引用了不同的对象,改变一个对象的状态不会导致另一个对象的改变。
请注意,这适用于 c# 中的引用类型,即类和接口对象,而不适用于值类型lile int
、long
等struct
推荐阅读
- faunadb - 我可以在一个请求中运行多个动物数据库事务吗?
- python - Python解析文件中的所有行并按文件夹结构拆分它们
- laravel - 数据与来自 axios vuejs 的响应不匹配
- sql-server - 从 .NET 应用程序连接到 Azure 托管服务器失败,但从命令行连接时有效
- python - Pyglet 2d 相机 OpenGL
- eclipse - eclipse 启动器不存在
- python - 从列中查找第一个非空值
- html - 撰写多段文章时引导溢出宽度
- android - 如何使用限制和偏移来限制内容解析器(android)的数据?
- php - 如何有效地将数据存储到 Laravel 8 缓存(文件)中的缓存中?