C#中的foreach循环会将同一项添加到列表中

7

我正在使用简单的foreach循环时遇到了问题。我想把数据库中的数据添加到我的列表中。

IList<DeliveredTaskModel> deliveredTaskModel = new List<DeliveredTaskModel>();
// lines of code 

if (materialUsed.Count > 0)
{
    foreach (var material in materialUsed)
    {
        var deliveryModel = new DeliveredTaskModel();
        deliveryModel.Info = materialUsed[0].SubPartCode;
        deliveryModel.Description = materialUsed[0].Description;
        deliveryModel.Qty = materialUsed[0].Qty;
        deliveredTaskModel.Add(deliveryModel);
    }
}

当我在foreach上设置断点时,我可以看到materialUsed中有4个不同的项目。然而,当我使用foreach时,它只是将4个相同的项目添加到网格中。 我猜它会不断地添加相同的项目,但为什么呢?有人能解释一下吗?

2
使用 material 替代第一个项目 materialUsed[0] - Alessandro D'Andria
3
你总是在访问materialUsed集合的第一个元素。因此,不要使用materialUsed[0],而是使用在你的foreach循环中声明的变量material - Nino
4个回答

16

你总是不断地使用索引零进行访问。纠正的选项:

  1. 如果你使用 foreach,请使用:

    foreach (var material in materialUsed)
    {
        var deliveryModel = new DeliveredTaskModel();
        deliveryModel.Info = material.SubPartCode;
        deliveryModel.Description = material.Description;
        deliveryModel.Qty = material.Qty;
        deliveredTaskModel.Add(deliveryModel);
    }
    
  2. 如果您使用索引器,请改用for循环

    for(int i = 0; i < materialUsed.Count, i++)
    {
        var deliveryModel = new DeliveredTaskModel();
        deliveryModel.Info = materialUsed[i].SubPartCode;
        deliveryModel.Description = materialUsed[i].Description;
        deliveryModel.Qty = materialUsed[i].Qty;
        deliveredTaskModel.Add(deliveryModel);
    }
    
  3. 那么使用属性初始化程序会更好:

    foreach (var material in materialUsed)
    {
        deliveredTaskModel.Add(new DeliveredTaskModel
        {
            Info = material.SubPartCode,
            Description = material.Description,
            Qty = material.Qty
        });
    }
    
  4. 然后使用linq,您可以通过.Select实现它。

  5. var deliveredTaskModel = materialUsed.Select(material => new DeliveredTaskModel
        {
            Info = material.SubPartCode,
            Description = material.Description,
            Qty = material.Qty
        }).ToList();
    

我建议你选择最后一个选项 :)

最后一条评论 - 你的if语句 (materialUsed.Count > 0) 是多余的,因为如果集合为空,它不会进入循环


1
你应该将 materialUsed 与 'null' 进行比较,而不是大于0。 - WhileTrueSleep
@WhileTrueSleep - 真的。我假设集合不为null且没有空项。 - Gilad Green
1
@Gilad,你的方法真是太棒了!这真的非常重要。最好使用链接的方式来实现。请在你的链接语句中使用model变量而不是material。再次感谢。 - PatsonLeaner

3

您的循环中引用了相同的固定索引:

deliveryModel.Info = materialUsed[0].SubPartCode;

你需要使用循环变量:

deliveryModel.Info = material.SubPartCode;

3

在foreach循环的每次迭代中,应该使用当前项而不是引用列表。尝试这样做:

IList<DeliveredTaskModel> deliveredTaskModel = new List<DeliveredTaskModel>();

        if (materialUsed.Count > 0)
        {
            foreach (var material in materialUsed)
            {
                var deliveryModel = new DeliveredTaskModel();
                deliveryModel.Info = material .SubPartCode;
                deliveryModel.Description = material .Description;
                deliveryModel.Qty = material .Qty;
                deliveredTaskModel.Add(deliveryModel);
            }
        }

1
IList<DeliveredTaskModel> deliveredTaskModel = new List<DeliveredTaskModel>();
// lines of code 

if (materialUsed.Count > 0)
{
    foreach (var material in materialUsed)
    {
        var deliveryModel = new DeliveredTaskModel();
        deliveryModel.Info = material.SubPartCode;
        deliveryModel.Description = material.Description;
        deliveryModel.Qty = material.Qty;
        deliveredTaskModel.Add(deliveryModel);
    }
}

materialUsed[0]是你的列表中的第一个元素,无论列表有多少个元素,你都应该始终取第一个,你应该取当前的元素"material"


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接