同一个类的两个对象,一个被覆盖

时间:2014-05-14 13:23:38

标签: c# oop

我有两个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分配给局部变量,那应该创建该类的新实例,对吧?

5 个答案:

答案 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。执行推迟到使用。这意味着对象本身可能没有变化,它本身可能从未被设置过,直到你查询它为止。

无论如何,您使用的模式相当奇怪。为什么不选择更加专注于存储库的数据访问方法。它比通过准单例汇集所有内容以获取数据要清晰得多。这也是一个更好的关注点分离。

@TMKeown有一个有趣的解决方案可能会解决当前的问题,但作为架构师,我会更关心你设置解决问题的方式。你为什么以这种方式汇集事物。如果有一个良好的动机,那么应该有一种模式可以保持动力,而不会带来相关的问题(一个对象神奇地成为另一个)。

答案 4 :(得分:0)

要扩展其他答案,ProductInformation引用类型,引用类型始终传递按引用。 此外,如果在类级别声明它,则两个调用都将返回相同的实例,此外调用代码接收{em>同一实例的ProductInformation object,因为它在类级别声明并且在两个方法调用中都使用相同的query对象。

因此,如果将该变量移动到这些方法内部,则可以实现使用ProductInformation对象的单独实例的想法,因此当方法调用退出时会被销毁,并在下一个方法调用开始时重新创建。

有关内存管理,引用和值类型的更多信息,请访问Eric Lippert的博客: