递归循环正在更新通用列表中的所有属性

时间:2011-06-07 10:22:07

标签: c#

我有以下方法,它递归地创建一个通用列表。我得到了一些有趣的结果。始终使用最后一个值覆盖属性CurrentAllocation。

以下是有问题的行。

courierTypeRegion.CurrentAllocation = remaining;
courierTypeRegionOutput.Add(courierTypeRegion);

以下是整个方法

public static List<CourierTypeRegion> FindClosest2(decimal quantity, decimal remaining, ICollection<CourierTypeRegion> courierTypeRegions, List<CourierTypeRegion> courierTypeRegionOutput)
        {
            var processed = false;
            var courierOrderByDesc = courierTypeRegions.OrderByDescending(x => x.CourierType.PalletsPerTrailer).ToList();
            var courierCount = courierOrderByDesc.Count();
            var courierCurrent = 0;
            foreach (var courierTypeRegion in courierOrderByDesc)
            {

                if (remaining >= courierTypeRegion.CourierType.PalletsPerTrailer && !processed)
                {
                    courierTypeRegion.CurrentAllocation = courierTypeRegion.CourierType.PalletsPerTrailer;
                    courierTypeRegionOutput.Add(courierTypeRegion);
                    processed = true;
                }

                if (!processed)
                {
                    if (courierOrderByDesc[courierCurrent + 1] != null)
                    {
                        if (remaining > courierOrderByDesc[courierCurrent + 1].CourierType.PalletsPerTrailer)
                        {
                            courierTypeRegion.CurrentAllocation = remaining;
                            courierTypeRegionOutput.Add(courierTypeRegion);
                            processed = true;
                        }
                    }
                }
                courierCurrent++;
            }

            if (!processed)
            {
                if (courierTypeRegions.Count > 0)
                {
                    var courierTypeRegionRemaining =
                        courierTypeRegions.Where(x => x.CourierType.PalletsPerTrailer >= remaining).OrderByDescending(
                            x => x.CourierType.PalletsPerTrailer).SingleOrDefault();
                    if (courierTypeRegionRemaining != null) courierTypeRegionOutput.Add(courierTypeRegionRemaining);
                    processed = true;
                }
            }


            var currentRemaining = quantity - courierTypeRegionOutput.Sum(x => x.CourierType.PalletsPerTrailer);

            if (currentRemaining > 0)
            {
                FindClosest(quantity, currentRemaining, courierTypeRegions, courierTypeRegionOutput);
            }

            return courierTypeRegionOutput;
        }

1 个答案:

答案 0 :(得分:1)

'CourierTypeRegion'是一个适用于整个foreach循环的实例,它不会在每次循环迭代时被实例化和销毁。您正在重复将相同的实例添加到列表中。最后得到一个列表,其中所有项引用循环中的最后一个值。

您需要按如下方式更改foreach循环:

foreach (var courierTypeRegion in courierOrderByDesc)
            {
var courierRegionCopy = courierTypeRegion;    
                if (remaining >= courierTypeRegion.CourierType.PalletsPerTrailer && !processed)
                {
                    courierRegionCopy.CurrentAllocation = courierTypeRegion.CourierType.PalletsPerTrailer;
                    courierTypeRegionOutput.Add(courierRegionCopy);
                    processed = true;
                }

                if (!processed)
                {
                    if (courierOrderByDesc[courierCurrent + 1] != null)
                    {
                        if (remaining > courierOrderByDesc[courierCurrent + 1].CourierType.PalletsPerTrailer)
                        {
                            courierRegionCopy.CurrentAllocation = remaining;
                            courierTypeRegionOutput.Add(courierRegionCopy);
                            processed = true;
                        }
                    }
                }
                courierCurrent++;
            }