C# 在 foreach 循环中修改列表项

C# Modify List item while in a foreach loop

正如标题所说,我试图在 foreach 循环中编辑 列表项 。我知道这是不可能,所以我寻求解决这个问题的解决方案。

由于这是直接从 MySQL 服务器获取数据,因此需要在此循环内完成并使用正确的索引。 我尝试使用第二个列表并在 foreach 循环之外更改数据,但这并没有考虑项目的索引位置。

foreach (string friend in friendsOnline)
{
    query = "SELECT `username` FROM `accounts` WHERE email = '" + friend + "'";
    
    cmd = new MySqlCommand(query, conn);
    rdr = cmd.ExecuteReader();
                
    while (rdr.Read())
    {
        for (int i = 0; i<friendsOnline.Count; i++)
        {
            if (friendsOnline[i].Contains(friend))
            {
                friendsOnline[i] = rdr[0].ToString();
            }
        }
    }
}

据我所知,您在 friendsOnline:

中有电子邮件
string[] friendsOnline = new[] {
  "Me@Shire.com",
  "Dark.Lord@Mordor.gov",
};  

并且您想将这些 电子邮件 更改为 姓名:

string[] friendsOnline = new[] {
  "Frodo Baggins",
  "Sauron the Black",
};  

首先,我建议只执行一次 query:SQL 太慢了,无法在循环中执行 运行;相反,您可以构建一个 dictionary 哪个电子邮件对应于哪个索引:

using System.Linq;

...

// eMail - indexes correspondence
Dictionary<string, int[]> dict = friendsOnline
  .Select((name, index) => (name : name, index : index))
  .GroupBy(pair => pair.name, pair => pair.index, StringComparer.OrdinalIgnoreCase)
  .ToDictionary(group => group.Key, group => group.ToArray());

// We take all users (no WHERE), but once
// We read both username and email
string sql = 
  @"SELECT `username`,
           `email` 
      FROM `accounts`";
                
//DONE: using - we should Dispose IDisposable Command and Reader
using cmd = new MySqlCommand(sql, conn);
using rdr = cmd.ExecuteReader();

while (rdr.Read()) {
  string name = Convert.ToString(rdr[0]);
  string mail = Convert.ToString(rdr[1]); 

  // If we have correspondent indexes, we change friendsOnline
  if (dict.TryGetValue(mail, out var indexes))
    foreach (var index in indexes)
      friendsOnline[index] = name;
}