C# 将列表中某项的属性值推送到该列表中的下一项

C# 将列表中某项的属性值推送到该列表中的下一项,c#,list,for-loop,foreach,C#,List,For Loop,Foreach,我有两个对象,比如Amount,NewAmount,它们都有下面的属性 public class Amount { public Int64 Id { get; set; } public Int64 Amt1 { get; set; } public Int64 Amt2 { get; set; } } public class NewAmountDo { public Int64 newAmt { get; set; } } 我有一个包含一些值的Amount

我有两个对象,比如Amount,NewAmount,它们都有下面的属性

public class Amount
{
    public Int64 Id { get; set; }
    public Int64 Amt1 { get; set; }
    public Int64 Amt2 { get; set; }
} 
public class NewAmountDo
{
   public Int64 newAmt { get; set; }
}
我有一个包含一些值的Amount列表和一个包含一个值的NewAmount对象

List<Amount> amountListObject = new List<Amount>();
Amount amount = new Amount();
Amount amount1 = new Amount();
Amount amount2 = new Amount();
Amount amount3 = new Amount();
NewAmountDo newAmountDo = new NewAmountDo();
newAmountDo.newAmt = 50;
amount.Id = 1;
amount.Amt1 = 10;
amount.Amt2 = 100;
amountListObject.Add(amount);
amount1.Id = 2;
amount1.Amt1 = 20;
amount1.Amt2 = 200;
amountListObject.Add(amount1);
amount2.Id = 0;
amount2.Amt1 = 30;
amount2.Amt2 = 300;
amountListObject.Add(amount2);
amount3.Id = 0;
amount3.Amt1 = 40;
amount3.Amt2 = 400;
amountListObject.Add(amount3);

Console.WriteLine("Input ");
exising = amountListObject;

List<Amount> intermediate = new List<Amount>();
Amount newamount = new Amount();
intermediate.AddRange(amountListObject);
intermediate.Add(newamount);
下面是我得到的结果

Id : 1 , Amt1 : 50 , Amt2 : 100 
Id : 2 , Amt1 : 50 , Amt2 : 200
Id : 0 , Amt1 : 50 , Amt2 : 300
Id : 0 , Amt1 : 50 , Amt2 : 400
Id : 0 , Amt1 : 50 , Amt2 : 0
预期结果:

Id : 1 , Amt1 : 50 , Amt2 : 100
Id : 2 , Amt1 : 10 , Amt2 : 200
Id : 0 , Amt1 : 20 , Amt2 : 300
Id : 0 , Amt1 : 30 , Amt2 : 400
Id : 0 , Amt1 : 40, Amt2 : 0

有什么办法可以做到这一点吗?

问题是您在两个列表之间复制了Amount对象的引用。因此,当您将金额从上一个元素复制到中间列表时,基本上覆盖了将在下一个循环中使用的值

我看到了3种解决您问题的方法:

  • 对于您的金额类型,请使用结构而不是类。这将执行值复制,而不是引用复制,因此两个列表中不会有相同的实例,也不会有任何冲突

  • 如果您确实需要将您的类型设置为,则可以执行复制构造函数并复制中间列表中的项,如下所示:

    intermediate.AddRange(amountListObject.Select(o => new Amount(o)));
    
    Int64 previous;
    for (int i = 0; i < intermediate.Count; i++)
    {
        if (i == 0)
        {
            previous = intermediate[i].Amt1;
            intermediate[i].Amt1 = newAmountDo.newAmt;
        }
        else
        {
            Int64 temp = intermediate[i].Amt1;
            intermediate[i].Amt1 = previous;
            previous = temp;
        }
    }
    
    这样,列表中仍然会有引用,但每个引用都会指向类型Amount的不同实例,因此不会发生冲突

  • 如果要避免对象的任何副本,则需要修改代码,以便在foreach中使用中间值来保留以前的值,如下所示:

    intermediate.AddRange(amountListObject.Select(o => new Amount(o)));
    
    Int64 previous;
    for (int i = 0; i < intermediate.Count; i++)
    {
        if (i == 0)
        {
            previous = intermediate[i].Amt1;
            intermediate[i].Amt1 = newAmountDo.newAmt;
        }
        else
        {
            Int64 temp = intermediate[i].Amt1;
            intermediate[i].Amt1 = previous;
            previous = temp;
        }
    }
    
    Int64先前版本;
    for(int i=0;i

  • 首先为定义的类声明构造函数,它将有助于初始化,并为代码提供更好的可读性

    public class Amount
        {
            public Int64 Id { get; set; }
            public Int64 Amt1 { get; set; }
            public Int64 Amt2 { get; set; }
    
            public Amount(Int64 Id, Int64 Amt1, Int64 Amt2)
            {
                this.Id = Id;
                this.Amt1 = Amt1;
                this.Amt2 = Amt2;
            }
        }
        public class NewAmountDo
        {
            public Int64 newAmt { get; set; }
    
            public NewAmountDo(Int64 newAmt)
            {
                this.newAmt = newAmt;
            }
        }
    
    现在,初始化将更加干净:

    List<Amount> amountListObject = new List<Amount>();
    
    Amount amount = new Amount(1,10,100);
    Amount amount1 = new Amount(2,20,200);
    Amount amount2 = new Amount(0,30,300);
    Amount amount3 = new Amount(0,40,400);
    NewAmountDo newAmount = new NewAmountDo(50);
    amountListObject = new List<Amount>() { amount, amount1, amount2, amount3 };
    
    List amountListObject=new List();
    金额=新金额(1,10100);
    金额1=新金额(2,20200);
    金额2=新金额(0,30300);
    金额3=新金额(0,40400);
    NewAmountDo newAmount=新的NewAmountDo(50);
    amountListObject=new List(){amount,amount1,amount2,amount3};
    
    现在问题解决了:

    Int64 shiftedAmt = 0;
            for (int i = 0; i < amountListObject.Count; i++)
            {                
                /* First element in the list */
                if (i == 0)
                {
                    /* save the amt1 property value for shifting */
                    shiftedAmt = amountListObject[i].Amt1;
                    /* Switch to the new amount (if you need to add the new to the old just replace with +=) */
                    amountListObject[i].Amt1 = newAmount.newAmt;
                }
                else
                {
                    /* Shift the value */
                    Int64 temp = amountListObject[i].Amt1;
                    amountListObject[i].Amt1 = shiftedAmt;
                    shiftedAmt = temp;
                }
            }
            /* Create new Amount object for the last shifted amt1 value */
            Amount _amount = new Amount(0, shiftedAmt, 0);
            amountListObject.Add(_amount);
    
    Int64移位金额=0;
    for(int i=0;i