我有两个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分配给局部变量,那应该创建该类的新实例,对吧?
答案 0 :(得分:3)
&#34;因为我在我的测试方法中将thisProduct分配给局部变量, 应该创建类的新实例,对吗?&#34;
不,分配参考不会自动创建新实例。
如果您使用相同的对象从数据库中读取,然后将该对象分配给变量,希望它将创建一个单独的实例,那么这就是问题所在。您将最终得到对同一对象的两个引用,因此当您将下一个对象的数据读入其中时,它将覆盖以前的数据。
您应该为要读取的每个对象创建一个新实例。
答案 1 :(得分:2)
看起来不像是一个局部变量:
ProductInformation thisProduct;
ExecuteQuery(int i)
{
switch (i)
case 10:
thisProduct = GiftCard();
break;
case 9:
thisProduct = GiftCertificate();
break;
return thisProduct;
}
您的Query
类用于加载两者,查询对象引用相同的ProductInformation实例。在我看来,你有两个选择:
- 使用2 query
个实例,因为你的查询类有状态(坏主意)。
- 将ProductInformation
此产品变量移到 ExecuteQuery()
方法中。
答案 2 :(得分:1)
giftcard和giftCertificate都是相同的实例,第二个语句只是更改现有对象。 我想放
thisProduct = new ProductInformation();
在ExecuteQuery方法中的switch语句之前应该有所帮助。此外,看起来这个产品不应该在类级别范围内。
ProductInformation thisProduct;
public ProductInformation ExecuteQuery(int i)
{
thisProduct = new ProductInformation();
switch (i)
case 10:
thisProduct = GiftCard();
break;
case 9:
thisProduct = GiftCertificate();
break;
return thisProduct;
}
答案 3 :(得分:0)
这里的部分问题是使用LINQ。执行推迟到使用。这意味着对象本身可能没有变化,它本身可能从未被设置过,直到你查询它为止。
无论如何,您使用的模式相当奇怪。为什么不选择更加专注于存储库的数据访问方法。它比通过准单例汇集所有内容以获取数据要清晰得多。这也是一个更好的关注点分离。
答案 4 :(得分:0)
要扩展其他答案,ProductInformation
是引用类型,引用类型始终传递按引用。
此外,如果在类级别声明它,则两个调用都将返回相同的实例,此外调用代码接收{em>同一实例的ProductInformation object
,因为它在类级别声明并且在两个方法调用中都使用相同的query
对象。
因此,如果将该变量移动到这些方法内部,则可以实现使用ProductInformation对象的单独实例的想法,因此当方法调用退出时会被销毁,并在下一个方法调用开始时重新创建。
有关内存管理,引用和值类型的更多信息,请访问Eric Lippert的博客: