我正在使用 Unity。我正在使用 IEnumerable.Select() 获取类型列表并将它们(作为组件)添加到 GameObject。 运行这个:
var newObjects = types.Select(t => (IGameManager)gameObject.AddComponent(t));
实际上将 两个 相同类型的组件添加到有问题的游戏对象中,尽管 newObjects 只包含对一个组件的引用。另一个创建的组件只是 float ,没有返回引用。 运行这个:
foreach(var t in types)
{
newObjects.Add((IGameManager)gameObject.AddComponent(t));
}
有效,并且只将每种组件类型中的一个添加到游戏对象。但是,它看起来有点丑。 (IGameManager 是所有相关类型实现的接口(interface)。)
我可以只使用 foreach 循环,但这并不完全 Eloquent ,此外,我在网上找不到任何解释这种行为的文章,因此我的好奇心越来越强。
所以,我的问题是:为什么 Select() 每次输入都会调用指定的函数两次,但只返回结果数据的一个副本?我该如何修复/预防/补偿这种行为?
谢谢!
最佳答案
你没有在你使用它的地方提供周围的代码,你给出的行实际上在那一点上没有做任何事情,没有评估,只是设置了一个表达式树。
随意修改您的代码并假设您可以访问游戏对象上的组件
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
您使用您的代码创建了一个表达式树,每次您对它执行某些操作时,它都会触发其中的表达式。我猜这就是发生在你身上的事情。您可以在我的代码中看到,每次您询问计数时,您都会在游戏对象中获得更多对象。
为避免这种情况,通过将其转换为列表或数组来评估一次:-
var newObjects = types.Select(t => (IGameManager)gameObject.AddComponent(t)).ToList();
关于C# - LINQ Select() 调用函数两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43795922/