0

I'm using foreach to transfer data from list to another but when adding value updated automatically to last value added. For example:

list1 = [1,2,3]
list2 = new List<Model>()

foreach(var item in list1) {
   list2.Add(item)
}

the result in list2 is [ 3, 3, 3]

Actually example is below :

var _sizes = new List<ProductsSize>();
var _size = new ProductsSize();

if (model.Dynamic_ProductsSize.Count > 0)
{
    foreach (var item in model.Dynamic_ProductsSize)
    {
        _size.SizeId = item;
        _sizes.Add(_size);
    }
}
model.ProductsSize = _sizes.ToList();

I need to know why it only takes the last item and what is the solution for this case

1
  • 2
    Because you are adding the same object each time. You need to declare var _size = new ProductsSize(); inside the foreach loop Commented Aug 3, 2018 at 11:40

2 Answers 2

3

You only have one ProductsSize object:

var _size = new ProductsSize();

And you keep modifying that same object. All references to that object, including any list elements it's been added to, get updated when you modify that one object.

Instead, create your new object in the loop:

foreach (var item in model.Dynamic_ProductsSize)
{
    var _size = new ProductsSize();
    _size.SizeId = item;
    _sizes.Add(_size);
}

That way each element in the list is a new object instead of the same object added multiple times.


Side note, you have a few things in the code which aren't necessary. Checking the length before the loop, for example, as well as converting a list to a list at the end.

In fact, I imagine all of the code shown can be shortened to simply this:

model.ProductsSize = model.Dynamic_ProductsSize.Select(p => new ProductsSize { SizeId = p }).ToList();

In which case you're also just converting one model property to another model property. Why not put this logic in the model itself and skip the whole thing?

public IEnumerable<ProductsSize> ProductsSize
{
    get { return this.Dynamic_ProductsSize.Select(p => new ProductsSize { SizeId = p });
}

Unless there's a particular reason you want the same data twice in two different properties that isn't clear from this code, having one set of data and just different views/calculations/etc. of that data is often preferred.

Sign up to request clarification or add additional context in comments.

2 Comments

It should also be noted that the ToList() call at the end (model.ProductsSize = _sizes.ToList();) is completely unnecessary
@CamiloTerevinto: Indeed. As is the check for if (model.Dynamic_ProductsSize.Count > 0). And the loop body itself can be shortened to one line. Now that I think about it, all of the code shown can be just a single LINQ projection...
0

Create a new object before adding it to the list. You can use the object initializer syntax to keep it concise:

 if (model.Dynamic_ProductsSize.Count > 0)
{
    foreach (var item in model.Dynamic_ProductsSize)
    {
        _sizes.Add(new ProductsSize(){SizeId = item});
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.