Unity3D中的C#匿名函数范围

时间:2016-10-20 13:54:38

标签: unity3d anonymous-function

我在Unity3D中制作模拟项目时遇到了这种令人费解的行为。

基本上,我使用循环变量在循环中创建匿名函数,并将所有这些函数添加到队列中进行处理。
Unity3D Monobehavior中的奇怪案例是它们仅在最后一个循环中被调用变量

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)通过打印最后一个值(&#34; 3&#34;)3次而不是1,2,3。我尝试了各种方法来规避和以下工作没有明显原因: 将Critical Section更改为以下块可解决此问题:

LOL another = l;
Func<int> func = () =>
{
    Debug.Log(another.ID);
    return 0;
};

如果有人可以回答(Unity Bug Fix Team似乎并不关心),将会很高兴。

1 个答案:

答案 0 :(得分:0)

你正面临着关闭的问题。

请参阅此问题:What are 'closures' in C#?

试试这个。它只是一样,但并不完全,因为你声明了一个&#34; new&#34;循环中lol

for( int index = 0 ; index < lols.Count ; ++index )
{
    Lol l = lols[index];
    Func<int> func = () =>
    {
        Debug.Log(l.ID);
        return 0;
    };
    fs.Add(func);
}

如果不起作用,请尝试:

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 ;
}

我必须承认,我对闭合感到不舒服。

相关问题