简体   繁体   English

无法从列表中删除项目

[英]Can't remove item from List

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. 我尝试从DeleteProduct方法中的产品中删除项目,并且Remove方法返回true但所有项目仍在列表中,我无法弄清楚原因。

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. 然后在DeleteProduct方法中,其中一个项删除并执行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");
    }
}

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. 通过调用ToList()您将生成一个新列表,并从新创建的列表中删除该产品。 In order to make the code work, change the products field to type List : 为了使代码有效,请将products字段更改为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() . 这样,您可以使用列表的方法,而不必ToList()转换或使用ToList() You can call Remove directly on the products field: 您可以直接在产品字段上调用Remove

products.Remove(product);

When you do products.ToList() you are creating a new list. 当您执行products.ToList()您将创建一个新列表。 So, when you do products.ToList().Remove(product) , you are removing the product from this new list. 因此,当您执行products.ToList().Remove(product) ,您将从此新列表中删除该产品。

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. 或者,您可以更改静态变量products的类型为List<ProductViewModel> ,因此您不必创建新实例。

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). 所述ToList是不必要的,因为它创建一个 List ,并将它们去除product从该新的 List (其基本上是没有意义的)。

The FirstOrDefault is unnecessary since Remove will take care of the only remove this item if it is already there problem for you. FirstOrDefault是不必要的,因为如果已经存在问题, Remove将负责删除此项目 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 . IEnumerable作为其“原始”类型( List )没有任何好处,并且使用IEnumerable会删除调用Remove

Also consider using ConcurrentBag rather than List - for thread safety . 还考虑使用ConcurrentBag而不是List - 用于线程安全

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM