What is the best way to modify a list in a 'foreach' loop?
The collection used in foreach is immutable. This is very much by design.
As it says on MSDN:
The foreach statement is used to
iterate through the collection to get
the information that you want, but can
not be used to add or remove items
from the source collection to avoid
unpredictable side effects. If you
need to add or remove items from the
source collection, use a for loop.
The post in the link provided by Poko indicates that this is allowed in the new concurrent collections.
C# Modify List item while in a foreach loop
As I can see, you have emails in the friendsOnline
:
string[] friendsOnline = new[] {
"Me@Shire.com",
"Dark.Lord@Mordor.gov",
};
and you want to change these emails into names:
string[] friendsOnline = new[] {
"Frodo Baggins",
"Sauron the Black",
};
First of all, I suggest executing query just once: SQL is too slow to be run in a loop; instead you can build a dictionary which eMail corresponds to which indexes:
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;
}
Modifying list inside foreach loop
Rather than use a foreach
construct, a for
loop would allow you to alter the list.
for (var x = 0; x < list.Count; x++) {
}
How update a list in a foreach
Use for for modifing lists. NOT foreach.
As it says on MSDN:
The foreach statement is used to iterate through the collection to get the information that you want, but can not be used to add or remove items from the source collection to avoid unpredictable side effects. If you need to add or remove items from the source collection, use a for loop.
List<Envolvido> mylist = t.Result;
for (int index = 0; index < mylist.Count(); index++)
{
var items = mylist.ToList();
Envolvido envolvido = items[index];
envolvido.SUSPID= Convert.FromBase64String(envolvido.SUSPID);
envolvido.IVNOME = Convert.FromBase64String(envolvido.IVNOME);
}
How to modify list entries during for loop?
It's considered poor form. Use a list comprehension instead, with slice assignment if you need to retain existing references to the list.
a = [1, 3, 5]
b = a
a[:] = [x + 2 for x in a]
print(b)
ForEach will not alter/change items in list C#
You should use the Select
function if you want to get a different result.
var items = listBox1.Items.Cast<string>().ToList();
listBox1.Items = items.Select(item => (!chkBox1.Checked) ? "move " + item : "move -check " + item).ToList();
The ForEach
function can do something according to a collection value, but can't do it to the values themselves.
The Select
function will create a new collection according to the given collection.
Edit
About your edit of successfully changing values by using
tapes.ForEach(x => x.vItem = "tapelib 3592 -eject " + x.vItem);
You need to understand how passing argument by value/reference works.
In c#, when writing var obj1 = new object()
, obj1
is a pointer to the new object()
that exists on the heap.
When you pass obj1
to a function public void Foo(object obj) { //... }
by calling Foo(obj1)
, the function will get the parameter as new pointer to the same object
on the heap.
Therefore, when you use ForeEach on the object itself,
object.ForEach(obj => obj = new object()) // No changed outside the Foreach
only the new pointer will be changed and it will point on a new object but the original pointer isn't changed.
But if you use it on an inner object,
object.ForEach(obj => obj.InnerObject = new object()) // Changed outside the Foreach
this will change the pointed inner object and the inner object will be changed.
Update ListT using foreach loop and Condition using LINQ/LAMBDA
foreach(var item in SeasonList.Where(x => x.Text == "ALL"))
{
item.Selected = false;
}
Related Topics
Calling a Function from a String in C#
What Are the Differences Between Generics in C# and Java... and Templates in C++
Mvvm: Tutorial from Start to Finish
Why Saving Changes to a Database Fails
Passing Strings from C# to C++ Dll and Back - Minimal Example
Is Is Possible to Export Functions from a C# Dll Like in VS C++
How to Call a C# Library from Native C++ (Using C++\Cli and Ijw)
Reach Control from Another Page. Asp.Net
How to Dynamically Generate HTML Code Using .Net'S Webbrowser or Mshtml.Htmldocument
Convert Webpage to Image from Asp.Net
How to Find the Text Within a Div in the Source of a Web Page Using C#
How to Convert HTML to Plain Text
What Is the Overhead of Creating a New Httpclient Per Call in a Webapi Client
Why Did I Get the Compile Error "Use of Unassigned Local Variable"
Convert a Unicode String to an Escaped Ascii String
Ignore Folders/Files When Directory.Getfiles() Is Denied Access