更新IEnumerable中的项目

nik*_*nik 12 c# linq

我需要更新IEnumerable列表中的值.

这是一个简短的IEnumerable示例:

IEnumerable<string> allsubdirs = new List<string>() { "a", "b", "c" };
Run Code Online (Sandbox Code Playgroud)

现在,如果我想为每个项添加时间戳,这不起作用:

allsubdirs.Select(a => a = a + "_" + DateTime.Now.ToString("hhmmss")).ToList();
Run Code Online (Sandbox Code Playgroud)

这也不是:

foreach (var item in allsubdirs)
            item = item + "_" + DateTime.Now.ToString("hhmmss");
Run Code Online (Sandbox Code Playgroud)

我让它像这样工作:

IEnumerable<string> newallsubdirs = allsubdirs.Select(a => a + "_" + DateTime.Now.ToString("hhmmss")).ToList();
        allsubdirs = newallsubdirs;
Run Code Online (Sandbox Code Playgroud)

但这似乎有点像作弊.请问这样做的正确方法是什么?

D S*_*ley 23

Linq用于查询,而不是更新.Linq查询根据投影,过滤器等返回新的集合.因此,您的选择是:

  • 将"new"集合保存回变量(如果需要,可以保存为新变量):

    allsubdirs = allsubdirs.Select(a => a = a + "_" + DateTime.Now.ToString("hhmmss")).ToList();
    
    Run Code Online (Sandbox Code Playgroud)
  • 使用可写接口IList<T>for循环:

    IList<string> allsubdirs = new List<string>() { "a", "b", "c" };
    
    for(int i=0; i<allsubdirs.Count(); i++)
        allsubdirs[i] = allsubdirs[i] + "_" + DateTime.Now.ToString("hhmmss");
    
    Run Code Online (Sandbox Code Playgroud)

主要区别在于,Select 不会修改原始集合,而for循环则会.

我的观点是,Select它更清洁,不是"作弊" - 你只是在原始系列的顶部添加一个投影.


teh*_*mas 5

D·斯坦利回答正确。我想补充他的答案,因为标题暗示Update item in IEnumerable只有一个项目需要更新。

正如D Stanely在他的回答中解释的那样:

Linq 用于查询,而不是更新。

使用 IList 等可写接口和 for 循环

对于更新单个项目,您可以检索要更新的项目的索引并使用该索引来更新它。

例如:

IList<string> allsubdirs = new List<string>() { "a", "b", "c" };
int index = allsubdirs.IndexOf("a");
allsubdirs[index] = "d";
Run Code Online (Sandbox Code Playgroud)