Переместить значение свойства элемента в списке к следующему элементу в этом списке
У меня есть два объекта, скажем 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 Object с одним значением
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);
Я пытаюсь добавить значение в свойстве newAmt в NewAmount Object к свойству Amt1 totalListObject и опустить значение Amt1 до значения 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
Есть ли способ добиться этого?
2 ответа
Проблема в том, что вы копируете ссылки на ваши объекты Amount между двумя списками. Поэтому, когда вы копируете сумму из предыдущего элемента в ваш промежуточный список, вы в основном перезаписываете значение, которое вы собираетесь использовать в следующем цикле.
Я вижу 3 решения вашей проблемы:
Используйте структуру вместо класса для вашего типа Amount. Это приведет к копированию значений вместо эталонной копии, поэтому у вас не будет одинакового экземпляра в двух списках, и у вас не будет никаких конфликтов.
Если вам действительно нужно, чтобы ваш тип был классом, вы можете создать конструктор копирования и скопировать ваши элементы в промежуточный список следующим образом:
intermediate.AddRange(amountListObject.Select(o => new Amount(o)));
Таким образом, вы по-прежнему будете иметь ссылки в своих списках, но каждая ссылка будет указывать на отдельный экземпляр вашего типа Amount, следовательно, никаких конфликтов.
Если вы хотите избежать какой-либо копии объектов, вам нужно будет изменить свой код, чтобы использовать промежуточное значение в вашем foreach, чтобы сохранить то, что было в предыдущей сумме, следующим образом:
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; } }
Сначала объявите конструктор для определенного класса, это поможет с инициализацией и улучшит читабельность кода.
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);