C# 从IEnumerable中删除项<;T>;它不起作用了

C# 从IEnumerable中删除项<;T>;它不起作用了,c#,asp.net-mvc,list,ienumerable,C#,Asp.net Mvc,List,Ienumerable,我正在尝试从IEnumerable网格列表中删除对象 我尝试了以下选项,但没有一个有效 value是ImportDataMappingModel GridList.ToList().RemoveAll(o => o.value==null); GridList=GridList.TakeWhile(o => o.value!=null); ToList返回网格列表的副本,您正在修改它,而不是原始网格列表。您不能从IEnumerable中删除项,因为它不可修改 尝试使用i收集尝试以下

我正在尝试从
IEnumerable网格列表中删除对象

我尝试了以下选项,但没有一个有效

value
ImportDataMappingModel

GridList.ToList().RemoveAll(o => o.value==null);
GridList=GridList.TakeWhile(o => o.value!=null);

ToList返回网格列表的副本,您正在修改它,而不是原始网格列表。您不能从
IEnumerable
中删除
项,因为它不可修改

尝试使用
i收集

尝试以下操作:

GridList = GridList.Where(o => o.value != null).ToList();
第一次尝试时,
GridList.ToList().RemoveAll(o=>o.value==null)
,创建列表的副本(调用
ToList()
),然后修改该副本,保持原始列表不变

您的第二次尝试,
GridList=GridList.TakeWhile(o=>o.value!=null)
,将创建一个枚举,当枚举时,该枚举将返回第一个null项(如果有)之前的所有非null项。但它实际上并没有枚举新的可枚举项,因此您永远不会实际创建新集合

要纠正第二次尝试,您需要做两件事:

  • 将TakeWhile替换为Where。例如,如果您有一个包含三个条目的列表,其中第一个和第三个条目不为null,而第二个条目为null,TakeWhile将只返回第一个条目。如果需要所有非空项,则需要使用Where

  • 调用ToList()将Where枚举器选择的项复制到新列表中


  • 这不起作用,因为它正在处理副本,而该副本未分配给任何对象

    GridList.ToList().RemoveAll(o => o.value==null);
    
    解决办法是:

    var list = GridList.ToList(); //create copy
    list.RemoveAll(o => o.value==null); //work on copy
    GridList = list; //assign copy to gridlist
    
    此版本不起作用,因为它将在
    o.value==null
    时停止使用(请注意,当您不想要的东西都在末尾时,它将起作用!):

    解决方案是在以下情况下使用:

    GridList = GridList.Where(o => o.value!=null);
    
    由于对“.ToList()”的调用创建了一个不同于GridList的List的新实例,因此此代码不会执行您想要的操作。因此,这段代码实际上将从新列表实例中删除所有空值项,而不是从“GridList”中删除

    GridList = GridList.TakeWhile(o => o.value!=null);
    
    这段代码实际上会执行您期望的操作,但是由于Linq命令在执行时有所不同,因此仅调用TakeWhile()不会立即执行,而只能在您尝试读取GridList的项之后执行。如果要强制执行,应在末尾调用“.ToList()”或“.ToArray()”,即:

    GridList = GridList.TakeWhile(o => o.value!=null).ToList();
    

    请描述“不工作”@psubsee2003所有其他答案解释问题所在。但是,它们都没有提出OP想要的解决方案。现在你有了我的+1结尾,意思是如果我有10个项,那么所有的空项都应该在末尾。我是说,如果末尾的项是
    o,TakeWhile似乎会起作用。value==null
    也许是LINQ查询的延迟执行导致了第二个查询的问题?
    GridList = GridList.TakeWhile(o => o.value!=null);
    
    GridList = GridList.TakeWhile(o => o.value!=null).ToList();