Reputation: 35
I try to remove item from products in DeleteProduct method and Remove method returns true but all items still in list and I can't figure out why.
As I understend products list creates at the first start of the application and at static constructor it fills with items. Then in DeleteProduct method one of the items removes and executes Products Method.
Please someone explane it!
public class ProductController
: Controller
{
private static IEnumerable<ProductViewModel> products = null;
static ProductController()
{
products = new List<ProductViewModel>
{
new ProductViewModel{Id = 0, Description = "Milk", Price = 21.0, IsAvailable = true, LastUpdate = DateTime.Now},
new ProductViewModel{Id = 1, Description = "Bread", Price = 10.10, IsAvailable = false, LastUpdate = DateTime.Now},
new ProductViewModel{Id = 2, Description = "Soure creame", Price = 34.5, IsAvailable = true, LastUpdate = DateTime.Now},
new ProductViewModel{Id = 3, Description = "Chocolate", Price = 31.0, IsAvailable = true, LastUpdate = DateTime.Now},
new ProductViewModel{Id = 4, Description = "Apples", Price = 1.0, IsAvailable = true, LastUpdate = DateTime.Now},
};
}
public ActionResult Products()
{
return View(products);
}
public ActionResult DeleteProduct(int id)
{
var product = products.FirstOrDefault(p => p.Id == id);
if (product != null)
products.ToList().Remove(product);
return RedirectToAction("Products");
}
}
Upvotes: 1
Views: 295
Reputation: 22456
The problem is in that line:
products.ToList().Remove(product);
By calling ToList()
you generate a new list and remove the product from the newly created list. In order to make the code work, change the products field to type List
:
private static List<ProductViewModel> products = null;
This way, you can use the methods of a list and do not have to cast or use ToList()
. You can call Remove
directly on the products field:
products.Remove(product);
Upvotes: 2
Reputation: 23898
Consider replacing:
var product = products.FirstOrDefault(p => p.Id == id);
if (product != null)
products.ToList().Remove(product);
with:
products.Remove(product);
and replacing:
private static IEnumerable<ProductViewModel> products = null;
with:
private static List<ProductViewModel> products = null;
The ToList
is unnecessary since it creates a new List
and them removes the product
from that new List
(which is basically pointless).
The FirstOrDefault
is unnecessary since Remove
will take care of the only remove this item if it is already there problem for you. The code as is basically checks twice whether the item is there before removing it.
The IEnumerable
has no benefits over leaving it as its 'raw' type (List
), and using IEnumerable
removes the ability to call Remove
.
Also consider using ConcurrentBag
rather than List
- for thread safety.
Upvotes: 0
Reputation: 1425
When you do products.ToList()
you are creating a new list. So, when you do products.ToList().Remove(product)
, you are removing the product from this new list.
You could do something like:
if (product != null)
{
List<ProductViewModel> productList = products.ToList();
productList.Remove(product);
products = productList;
}
Or, you could change so the static variable products
is of type List<ProductViewModel>
, so you wouldn't have to create a new instance.
Upvotes: 1