问题描述
在Unity3D中创建模拟项目时,我遇到了这种令人困惑的行为.
I came across this puzzling behavior while making a simulation project in Unity3D.
基本上,我正在使用要循环的变量在循环中创建匿名函数,并将所有这些函数添加到队列中进行处理.
Unity3D Monobehavior中奇怪的情况是它们仅在最后一个循环变量上被调用
Basically, I was creating anonymous functions in a loop using the variable being looped, and add all these functions to a queue for processing.
The curious case in Unity3D Monobehavior is that they are only called on the last looped variable.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
public class TestDist : MonoBehaviour {
int counter = 0;
// Use this for initialization
void Start () {
List<LOL> lols = new List<LOL>();
lols.Add(new LOL(1));
lols.Add(new LOL(2));
lols.Add(new LOL(3));
List<Func<int>> fs = new List<Func<int>>();
foreach (LOL l in lols)
{
//****** Critical Section *********
Func<int> func = () =>
{
Debug.Log(l.ID); //Prints "3" 3 times instead of
return 0; // "1", "2", "3"
};
//****** Critical Section *********
fs.Add(func);
}
foreach (Func<int> f in fs)
{
f();
}
}
// Update is called once per frame
void Update () {
}
}
class LOL
{
public long ID;
public LOL(long id)
{
ID = id;
}
}
该代码在普通的Visual Studio Console应用程序中运行良好,但在Unity3D上失败. (版本5.0)通过打印最后一个值("3")而不是1,2,3来打印3次.
我尝试了各种方法来绕过该方法,但以下方法却没有明显的原因起作用:将关键部分"更改为以下块可以解决此问题:
The code works good in plain Visual Studio Console application, but fails on Unity3D. (Version 5.0) by printing the last value ("3") 3 times instead of 1,2,3.
I tried various methods to circumvent and the following worked for no apparent reason :Changing the Critical Section to the following block solves the issue:
LOL another = l;
Func<int> func = () =>
{
Debug.Log(another.ID);
return 0;
};
如果有人可以回答(Unity Bug Fix Team似乎不在乎)会很高兴
Will be delighted if someone can answer (Unity Bug Fix Team does not seem to care)
推荐答案
您正面临关闭问题.
查看此问题: C#中的"closures"是什么?
试试看.它只是一样,但不是完全一样,因为您在循环中声明了新" lol
:
Try this instead. Its merely the same, but not completely since you declare a "new" lol
in your loop :
for( int index = 0 ; index < lols.Count ; ++index )
{
Lol l = lols[index];
Func<int> func = () =>
{
Debug.Log(l.ID);
return 0;
};
fs.Add(func);
}
如果它不起作用,请尝试:
If it does not work, try :
foreach (LOL l in lols)
{
fs.Add(GetFunction(l.ID));
}
// ...
private Func<int> GetFunction( int identifier)
{
Func<int> func = () =>
{
Debug.Log(identifier);
return 0;
};
return func ;
}
我必须承认,我对关闭并不满意.
I does not feel comfortable with closure, I must admit.
这篇关于Unity3D中的C#匿名函数作用域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!