First off, on the subject of Garbage. it doesn’t matter until you can actually see the impact in your game.
Secondly, @Invertex , your examples still produce garbage (because you use that foreach lol).
And no, Foreach can still produce garbage, it depends mostly on the collection or if you’re accessing a collection via an interface. Foreach on IEnumerable and IEnumerable always produces garbage, except on arrays (which are given special treatment). Even if the collection is using a struct as its Enumerator, if you access it via an IEnumerable, it will get boxed and generate garbage.
Again, because I think this is important to get across, it doesn’t matter until you can feel it! More often than not you’ll never feel it, or the code you’ve wasted time to pre-optimize ended up changing to something else. Optimizing ForEach is like the last thing you have to work on for performance leaks.
Finally you can use Closures inside a loop to carbon-copy the reference, even if the reference is changed later take this for example.
int count = 0;
var actions = new List<System.Action>();
for(int i =0; i< 10; i++)
{
count = i;
actions.Add( () => {Debug.Log(count)});
}
//this will print "9" ten times
for(int i =0; i< 10; i++)
{
actions[i].invoke();
}
Here, the variable thats used is in an external scope from where the lambada was defined which means the variable is shared on all delegates that use it.
However shift the code just so slightly…
var actions = new List<System.Action>();
for(int i =0; i< 10; i++)
{
int count = i; // closure reference!
actions.Add( () => {Debug.Log(count)});
}
//this prints "0" through "9"
for(int i =0; i< 10; i++)
{
actions[i].invoke();
}
suddenly you’re using closures. The compiler detects that the defined lambada is using a variable defined in the same environment (i.e. same scope), so it made a “carbon-copy” of said variable and that lambada brought that variable instance with them.
I love using closures when I get the chance, it allows me to pack extra data into an event handler. that said I always comment that I’m using closures, because its not always instantly obvious why some random variable was declared there for, especially for people who don’t know what closures are.