【问题标题】:Can't remove item from List无法从列表中删除项目
【发布时间】:2017-12-02 20:05:58
【问题描述】:

我尝试在 DeleteProduct 方法中从产品中删除项目,并且 Remove 方法返回 true,但所有项目仍在列表中,我不知道为什么。

据我了解,产品列表在应用程序的第一次启动时创建,并且在静态构造函数中填充了项目。然后在 DeleteProduct 方法中,其中一项删除并执行 Products 方法。

请有人解释一下!

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");
    }
}

【问题讨论】:

  • 你所做的是糟糕的做法(不要使用static 变量),但如果你首先测试products 是否为null,然后才将列表分配给它,它会起作用。
  • @StephenMuecke 我绝对不会将数据存储在静态变量中,也不会使用静态变量。只是想创建测试示例
  • @StephenMuecke 谢谢你的链接

标签: c# asp.net-mvc


【解决方案1】:

问题出在那一行:

products.ToList().Remove(product);

通过调用ToList(),您可以生成一个新列表并将产品从新创建的列表中删除。为了使代码正常工作,请将 products 字段更改为输入List

private static List<ProductViewModel> products = null;

这样,您可以使用列表的方法,而不必强制转换或使用ToList()。您可以在产品字段直接拨打Remove

products.Remove(product);

【讨论】:

  • @mjwills 感谢您的提示。我会更新答案。
  • 谢谢!我忘了 ToList 会生成新列表
【解决方案2】:

当您执行products.ToList() 时,您正在创建一个新列表。因此,当您执行 products.ToList().Remove(product) 时,您正在从这个新列表中删除该产品。

你可以这样做:

if (product != null)
{
    List<ProductViewModel> productList = products.ToList();
    productList.Remove(product);
    products = productList;
}

或者,您可以更改静态变量 products 的类型为 List&lt;ProductViewModel&gt;,这样您就不必创建新实例。

【讨论】:

    【解决方案3】:

    考虑更换:

    var product = products.FirstOrDefault(p => p.Id == id);
    
    if (product != null)
        products.ToList().Remove(product);
    

    与:

    products.Remove(product);
    

    和替换:

    private static IEnumerable<ProductViewModel> products = null;
    

    与:

    private static List<ProductViewModel> products = null;
    

    ToList 是不必要的,因为它创建了一个 new List 并且他们从那个 new List 中删除了 product(这基本上是没有意义的) .

    FirstOrDefault 是不必要的,因为Remove 会为您解决只有在它已经存在时才删除它的问题。 原样的代码基本上会检查两次项目在移除之前是否存在。

    IEnumerable 与将其保留为“原始”类型 (List) 相比没有任何好处,并且使用 IEnumerable 删除了调用 Remove 的能力。

    还可以考虑使用ConcurrentBag 而不是List - 代表thread safety

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-10
      • 2020-01-27
      • 1970-01-01
      • 2022-12-20
      相关资源
      最近更新 更多