我有两个对象,例如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);
我正在尝试将NewAmount Object中属性newAmt中的值添加到amountListObject的Amt1属性,并将Amt1的值下推到下一个listitem的Amt1值。但我得到了列表中所有Amt1中第一个Amt1的值。下面是我试过的代码
for (int i = 0; i < intermediate.Count; i++)
{
if (i == 0)
{
intermediate[i].Amt1 = newAmountDo.newAmt;
}
else
{
intermediate[i].Amt1 = exising[i - 1].Amt1;
}
}
以下是输入:
Id : 1 , Amt1 : 10 , Amt2 : 100
Id : 2, Amt1 : 20 , Amt2 : 200
Id : 0 , Amt1 : 30 , Amt2 : 300
Id : 0 , Amt1 : 40 , Amt2 : 400
以下是我得到的结果
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
有没有办法实现这个目标?
答案 0 :(得分:1)
问题是您在两个列表之间复制了Amount对象的引用。因此,当您将前一个元素的金额复制到中间列表时,您基本上会覆盖您将在下一个循环中使用的值。
我看到了3个问题的解决方案:
为 Amount 类型使用结构而不是类。这将进行值复制而不是参考副本,因此您不会在2个列表中拥有相同的实例,并且您不会有任何冲突。
如果您确实需要将您的类型设为类,则可以执行复制构造函数并将项目复制到中间列表中,如下所示:
intermediate.AddRange(amountListObject.Select(o => new Amount(o)));
这样,您的列表中仍会有引用,但每个引用都会指向您的类型Amount的不同实例,因此没有冲突。
如果您想避免任何对象副本,那么您需要修改代码以使用foreach中的中间值来保留前一个Amount中的内容,如下所示:
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;
}
}
答案 1 :(得分:1)
首先声明定义类的构造函数,它将有助于初始化并提供更好的代码可读性。
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 };
现在已解决的问题:
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);