Foreach 循环中的计算会影响迭代列表值



我遇到了一个相当奇怪的问题。我正在迭代一种 List,在我的循环中,我将迭代器变量分配给另一个局部对象。现在,更改该本地对象中的任何内容都会导致循环迭代的 List 发生变化。让我用代码示例来清除这一点。

var balances = DBHelperADO.Select("select * from Orders"); 
// balances is of type List<MyModel>
foreach (var item in balances)
{ 
    MyModel model = new MyModel();
    model = item;
    var thisQty = details.Where(x => x.Code == item.Code).Sum(x => x.QTY);
    // details is another List<MyModel> holding values from the GUI
    model.BLNC = model.BLNC - thisQty;
    model.VAL = (model.BLNC == 0) ? 0 : model.VAL - (thisQty * model.RATE);
    model.TABLE = "Orders";
    toUpdate.Add(model);  // toUpdate is a List<MyModel>                    
}

现在我的理解是迭代器变量(在本例中为项目)是只读的,当我编写时:

模型 = 项目;

我正在复制我的项目值。但是当我对模型对象进行计算时,它会导致余额列表上的相同更改。

我不明白为什么它会影响余额列表。我正在对本地范围的模型对象执行计算。那么为什么这些反映在迭代列表(余额)上。

请帮助我做错了什么。

问候

我假设余额中元素的类型是类型而不是结构

因此,存储在 itemmodel 中的内容是对此类实例的引用分配model = item;时,不会复制实例,而只会复制对实例的引用

现在,当您通过model.BLNC = ...访问该实例的属性时,您将更改原始实例的属性。这和打电话给item.BLNC = ...是一样的

初始行MyModel model = new MyModel()相当过时,因为您覆盖了对该新实例的引用。

要制作真实的副本,您可以尝试类似

MyModel model = new MyModel
{    
    BLNC = item.BLNC,
    VAL = item.VAL,
    TABLE = "Orders"
    // ... copy further properties
};

您还可以使用 LINQ Select 语句完全重写循环,如下所示:

var toUpdate = balances.Select(item => 
   {
        var thisQty = details.Where(x => x.Code == item.Code).Sum(x => x.QTY);
        var blnc = item.BLNC - thisQty;
        return new MyModel
        {
            BLNC = blnc,
            VAL = (blnc == 0) ? 0 : item.VAL - (thisQty * item.RATE),
            RATE = item.RATE,
            TABLE = "Orders"
        };
   }).ToList();

您可能需要将 MyModel 类的更多属性从item复制到新实例。如果嵌套查询出现问题,则可能需要使用 balances.AsEnumerable()

model = item;引用,而不是副本

model.BLNC = model.BLNC - thisQty;更新引用,即更新原始对象中的值。

toUpdate.Add(model);将原始

列表中对原始对象的引用添加回新列表。

最新更新