C# - LINQ Select() 调用函数两次

标签 c# linq select unity3d

我正在使用 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/

相关文章:

c# - nServiceBus UnicastBusConfig.MessageEndpointMappings.Endpoint

javascript - 如何从 javascript 函数将值设置为 gridview 文本框

java - 如何将为 Java Webservice 生成的 WSDl 转换为 C# 客户端?

c# - 将匿名类型转换为 List<KeyValuePair>

ASP.NET LINQ 数据库供应商

c# - 如何从 byte[] 中读取整数

c# - 如何使用 Linq 按相等性对 C# 中的对象进行分组

Mysql为选择添加新列

mysql 选择然后更新/加入?

vb.net - 返回数据集中表的前 5 条记录