C # call function - LINQ Select () twice

I am using Unity. I use IEnumerable.Select () to take a list of types and add them (as components) to GameObject. Doing this:

var newObjects = types.Select(t => (IGameManager)gameObject.AddComponent(t)); 

It actually adds two components of the same type to the gameObject in question, although newObjects only contains a reference to one. Another component created just floats around without returning a link. Doing this:

 foreach(var t in types) { newObjects.Add((IGameManager)gameObject.AddComponent(t)); } 

Only one of the component types in GameObject works and adds. But it looks somehow ugly. (IGameManager is an interface that is implemented by all types.)

I could just use the foreach loop, but it’s not very eloquent, and besides, I cannot find articles on the Internet explaining this behavior, and therefore my curiosity is getting better than me.

So my question is: why does Select () call the specified function twice on each input, but returns only one copy of the received data? And how do I fix / prevent / compensate for this behavior?

Thanks!

+5
source share
1 answer

You have not provided the surrounding code in which you use it, the line you give does not actually do anything at this moment, it does not evaluate anything, it just creates an expression tree.

By accepting some restrictions with your code and assuming that you can get to the Components in the game object

  var gameObject = new GameObject(); var types = new List<string>() { "a", "b", "c" }; var newObjects = types.Select(t => (IGameManager)gameObject.AddComponent(t)); // at this point, nothing has happened.... Console.WriteLine(gameObject.Components.Count()); // 0 Console.WriteLine(newObjects.Count()); // 3 - we trigger the selects Console.WriteLine(gameObject.Components.Count()); // 3 Console.WriteLine(newObjects.Count()); // 3 - we trigger the selects again Console.WriteLine(gameObject.Components.Count()); // 6 

with your code you have created an expression tree, every time you do something with it, it will run expressions inside it. I guess this is what happens to you. You can see here in my code that every time you request an account, you get more objects in your game objects.

To avoid this, evaluate it once, turning it into a list or array as follows: -

 var newObjects = types.Select(t => (IGameManager)gameObject.AddComponent(t)).ToList(); 
+9
source

All Articles