同一类的两个对象,其中一个被覆盖
本文关键字:一个 覆盖 两个 一类 对象 | 更新日期: 2023-09-27 18:03:14
我有两个类型为ProductInformation
的对象,它们包含productId、productName和price的属性。我还有一个方法,用于查询数据库中的这些信息,以填充产品类。
ProductInformation giftcard = query.ExecuteQuery(10) //this returns a giftcard
ProductInformation giftCertificate = query.ExecuteQuery(9) //this returns a gift certificate
我已经遍历了查询,并且可以确认,在运行第一行之后,礼品卡已成功填充。然而,不知何故,在我创建了礼品证书之后,它用礼品证书的属性覆盖了礼品卡对象。在我看来,它们应该是独立的对象。为了保留礼品卡,我遗漏了什么?
作为参考,我使用的查询基本上是
SELECT *
FROM Products
WHERE ProductName like '%gift card'
和
SELECT *
FROM Products
WHERE ProductName like '%gift certificate'
我唯一能想到的是,我的查询类有一个私有的ProductInformation对象,我用它来返回礼品卡和礼品证书,如
ProductInformation thisProduct;
public ProductInformation ExecuteQuery(int i)
{
switch (i)
case 10:
thisProduct = GiftCard();
break;
case 9:
thisProduct = GiftCertificate();
break;
return thisProduct;
}
private ProductInformation GiftCard()
{
using (SqlConnection con = new SqlConnection(conectionString))
{
con.Open();
return con.query<ProductInformation>(giftCardQuery).First();
}
}
private ProductInformation GiftCertificate()
{
using (SqlConnection con = new SqlConnection(connectionString))
{
con.Open();
return con.query<ProductInformation>(giftCertQuery).First();
}
}
,但因为我分配thisProduct局部变量在我的测试方法,这应该创建类的新实例,对吗?
"由于我将thisProduct分配给测试方法中的局部变量,这应该会创建类的新实例,对吧?"
不,赋值引用不会自动创建一个新的实例。
如果您使用相同的对象从数据库中读取,然后将该对象赋值给一个变量,希望它将创建一个单独的实例,那么这就是问题所在。您最终将得到对同一对象的两个引用,因此当您将下一个对象的数据读入其中时,它将覆盖前一个数据。
你应该为你想要读取的每个对象创建一个新的实例。
不像局部变量:
ProductInformation thisProduct;
ExecuteQuery(int i)
{
switch (i)
case 10:
thisProduct = GiftCard();
break;
case 9:
thisProduct = GiftCertificate();
break;
return thisProduct;
}
您的Query
类被用来加载两者,并且查询对象引用了相同的ProductInformation实例。在我看来,你有两个选择:
-使用2个query
实例,因为你的查询类有状态(坏主意)。
-将ProductInformation
thisProduct变量移动到 ExecuteQuery()
方法中。
giftcard和giftCertificate都是同一个实例,第二个语句只是改变了现有的对象。我猜是放
thisProduct = new ProductInformation();
ExecuteQuery方法中的before switch语句应该有帮助。而且看起来thisProduct不应该在类级别范围内。
ProductInformation该产品;
public ProductInformation ExecuteQuery(int i)
{
thisProduct = new ProductInformation();
switch (i)
case 10:
thisProduct = GiftCard();
break;
case 9:
thisProduct = GiftCertificate();
break;
return thisProduct;
}
这里的部分问题是LINQ的使用。执行被延迟到使用。这意味着对象本身可能没有变化,只是在您查询它之前它可能从未被设置过。
无论如何,您使用的模式相当奇怪。为什么不选择一种更侧重于存储库的数据访问方法呢?它比通过准单例来获取数据要干净得多。这也是一个更好的关注点分离。
@TMKeown有一个有趣的解决方案,可能会解决当前的问题,但作为架构师,我更关心您设置的解决问题的方式。你为什么要用这种方式把事情说出来。如果存在一个好的动机,那么就应该有一个模式来保持动机,而不会延续相关的问题(一个对象神奇地变成了另一个对象)。
进一步说明,ProductInformation
是一个引用类型,引用类型总是通过引用传递给。此外,如果您在类级别声明它,则两个调用将返回相同的实例,此外,调用代码接收到在类级别声明的ProductInformation object
的相同的实例,并且在两个方法调用中使用相同的query
对象。
因此,使用单独的ProductInformation对象实例的想法可以实现,如果你将该变量移动到这些方法中,那么它将在方法调用退出时被销毁,并在下一个方法调用开始时重新创建。
关于内存管理、引用和值类型的更多信息,请访问Eric Lippert的博客:
- Eric Lippert的博客-内存管理系列