2

抱歉,如果我很难正确表达这一点。OOP 不是我的专长,但我非常努力学习。

如何在循环的每三次迭代中创建一个对象的实例?

在一个循环中,我需要为一个对象赋值,但要赋值的属性将取决于 case 语句的结果。一旦分配了对象的每个属性,我就需要将该对象添加到相同类型的对象列表中。

如果我在进入循环之前创建对象,那么我的列表只会一遍又一遍地包含相同的结果,因为(我已经读过)该列表只包含对该对象的引用,并且如果随后更改了对象,清单也是如此。

如果我在循环中创建对象,那么显然,每次将其添加到列表时,我都会获得一个新对象,其中只有一个属性分配给它。该列表将包含不同的结果,但只会分配最后一个属性,因为每次都会创建一个新对象。

因此,我假设您可以做的是在所有属性都分配了值时创建一个新对象(或者在开始时没有分配值)。因此,由于我的对象具有三个属性,每次循环时,我想在 int iCounter 为 0 时添加一个新对象,添加值并增加 iCounter,然后当 iCounter 为 3 时,设置为 0。但是,当我尝试在 if 语句中创建对象时,程序的其余部分看不到该对象存在。

我还假设,我可能会尝试某种宏替换,这是我在 Fox 中通常会采用的方法,但是,(我已经读过)这在 c# 中是一个很大的禁忌。

有任何想法吗?

try
{
    cProducts Product = new cProducts();
    SqlConn2.Open();
    rdr2 = SqlComm2.ExecuteReader();
    int iScanLine = 0;
    while (rdr2.Read())
    {
        iScanLine++;
        Product.product = rdr2["product"].ToString();
        Product.sOrder = rdr2["order_id"].ToString();
        switch (rdr2["detail"].ToString())
        {
            case "Quantity":
                Product.quantity = Convert.ToInt16(rdr2["display_value"]) ;
                break;
            case "Option":
                Product.Option = rdr2["display_value"].ToString();
                break;
            case "Size":
                Product.Size = rdr2["display_value"].ToString();
                break;
        }
        if (iScanLine == 3)
        {
            lProducts.Add(Product);
            thisPage.sProducts.Add(lProducts[lProducts.Count() - 1]);
            iScanLine = 0;
        }

    }
}
4

5 回答 5

1

你可以改变这一点:

if (iScanLine == 3)
{
    lProducts.Add(Product);
    thisPage.sProducts.Add(Product); //<-- We know the object just added is still in Product
    iScanLine = 0;
    Product = new cProducts(); //<-- Create a new object to start populating
}

另外,我知道 .NET 框架很新,只有十年的历史,但您可以考虑阅读 命名指南

X 不要使用匈牙利符号。

于 2013-06-24T12:35:26.467 回答
1

看起来你有四列的表,其中每个产品表示在三个连续的行中

product | order_id | detail   | display_value
A         X          Quantity   5
A         X          Option     Foo
A         X          Size       XL
B         X          Quantity   2
...

你正在尝试阅读产品。我建议您存储当前产品名称并将其与上一个产品名称进行比较。如果名称被更改,那么您正在读取下一个产品的数据,因此您可以创建新产品并将其添加到产品列表中:

IDataReader reader = SqlComm2.ExecuteReader();
List<Product> products = new List<Product>();
Product product = null;

while (reader.Read())
{
    var name = reader["product"].ToString();

    if (product == null || product.Name != name) // check if new product
    {                        
        product = new Product(); // create new product                     
        product.Name = name; // fill name
        product.OrderId = reader["order_id"].ToString(); // and order
        products.Add(product); // add to products
    }

    object value = reader["display_value"]; // get value from row

    switch (reader["detail"].ToString())
    {
        case "Quantity":
            product.Quantity = Convert.ToInt16(value);
            break;
        case "Option":
            product.Option = value.ToString();
            break;
        case "Size":
            product.Size = value.ToString();
            break;
    }      
}

如您所见,我还重构了命名 -属性的PascalCase ,局部变量的camelCase,没有匈牙利符号。还引入了新的属性名称 -Product.Name而不是奇数Product.ProductOrderId而不是sOrder.

于 2013-06-24T13:13:13.243 回答
0

不确定我是否完全理解,但以下循环每三次使用计数器执行一次

int isThirdTime = 0; //Test condition for third time equality
while (true) //neverending loop
{
   if (isThirdTime == 3)//test for 3rd time
   {
      // add to list
      isThirdTime = 0; //reset counter
   }
   isThirdTime++; // Increase the counter
}
于 2013-06-24T12:48:52.430 回答
0

您反复将相同的内容添加Product到您的列表中,并且永远不会创建新的。当您到达循环的末尾时,看起来好像您只有一个项目。

添加项目后(在 中if (iScanLine == 3)),我怀疑您想创建一个新项目:Product = new cProducts().

另外,我想参考您在问题中提出的这一特定评论:

如果我在进入循环之前创建对象,那么我的列表只会一遍又一遍地包含相同的结果,因为(我已经读过)该列表只包含对该对象的引用,并且如果随后更改了对象,清单也是如此。

以下代码将导致将 5 个单独的对象添加到列表中:

List<cProducts> list = new List<cProducts>();
cProducts Product = new cProducts();
for (int i = 0; i < 5; i++)
{
    list.Add(Product);
    Product = new cProducts();
}

您是正确的,该列表仅包含对对象的引用-但您没有更改任何对象;你正在创造新的。这是一个基本的编程原则,我建议您在继续之前花时间了解它的工作原理。

于 2013-06-24T12:39:14.823 回答
0

使用 Modulus 运算符检查迭代变量是否可被期望值n整除

if(value % 3 == 0)
{
  //do stuff
}
value++;
于 2013-06-24T12:36:35.633 回答