道歉,如果我正在努力正确地说出这一点。 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;
}
}
}
答案 0 :(得分: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框架很新,只有十年之久,但您可以考虑阅读Naming Guidelines:
X不要使用匈牙利表示法。
答案 1 :(得分: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.Product
,OrderId
而不是sOrder
。
答案 2 :(得分:0)
使用Modulus运算符检查迭代变量是否可以被预期的n
值整除
if(value % 3 == 0)
{
//do stuff
}
value++;
答案 3 :(得分:0)
您反复向列表添加相同的Product
,并且永远不会创建新的if (iScanLine == 3)
。当你到达循环结束时,它看起来好像你只有一个项目。
在您添加商品后(Product = new cProducts()
内),我怀疑您要创建新商品:List<cProducts> list = new List<cProducts>();
cProducts Product = new cProducts();
for (int i = 0; i < 5; i++)
{
list.Add(Product);
Product = new cProducts();
}
。
此外,我想参考您在问题中提出的这一特定评论:
如果我在输入循环之前创建了对象,那么我的列表就是 一遍又一遍地包含相同的结果,因为(我已经读过)了 列表只包含对象的引用,如果对象是 然后改变了,列表也是如此。
以下代码将导致将5个单独的对象添加到列表中:
{{1}}
你是正确的,列表只包含对象的引用 - 但你没有改变任何对象;你正在创造新的。这是一个基本的编程原则,我建议你在继续之前花点时间了解它是如何工作的。
答案 4 :(得分: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
}