I noticed something interesting. I can change the elements of the array or assign a new array reference in foreach blocks, but I cannot do the same operations with collections, it gives an error. Why?? The following example gives an error
List<string> isimler = new List<string>() { "Ali", "Ayşe", "Fatma", "Mehmet" };
foreach (var (isim, index) in isimler.Select((isim, index) => (isim, index)))
{
isimler[index] += 10;
}
foreach(string isim in isimler)
{
Console.WriteLine(isim);
}
The following example does not give an error, It's working
string[] isimler = { "Ali", "Ayşe", "Fatma", "Mehmet" };
foreach (var (isim, index) in isimler.Select((isim, index) => (isim, index)))
{
isimler[index] += 10;
}
foreach(string isim in isimler)
{
Console.WriteLine(isim);
}
Because lists have code for explicit tracking for this (changing a tracking integer every time you make a change through the list API), and arrays do not. In the case of lists, this is especially important because if you add or remove elements it could significantly adversely impact the behaviour of the loop (imagine removing the zeroth element, for example). Since you cannot add/remove with arrays, this is less of a concern, and arrays are intended as very raw data types, without the overhead of such additional tracking fields.
As it happens there are APIs you could use with List<T> to have this specific change not be noticed. That doesn't make it a good idea to do so!
// DO NOT EVER DO THIS! Bad code! Only for illustration!
// This has *significant* risk of data corruption if you don't know
// **exactly** what you're doing.
var span = CollectionsMarshal.AsSpan(isimler);
foreach (var (isim, index) in isimler.Select((isim, index) => (isim, index)))
{
span[index] += 10;
}
and if you were going to do that: this would be much more efficient:
// STILL NOT A GOOD IDEA!
// or in isimler.AsSpan() in the case of string[]
foreach (ref string isim in CollectionsMarshal.AsSpan(isimler))
{
isim += 10;
}
Ultimately, though, in either event: if the contents of something are changing while you're looking at it: something risky is happening, whether or not it gets noticed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With