在Unity3D C#匿名函数范围(C# Anonymous Function Scope in U

2019-09-28 15:59发布

我碰到这个令人费解的行为来,同时使在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控制台应用程序很好,但未能在Unity3D。 (版本5.0)通过印刷的最后一个值(“3”)的3倍而不是1,2,3。
我尝试了各种方法来规避及以下工作没有明显的原因:改变临界区以下块解决了这个问题:

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

会很高兴,如果有人能回答(团结错误修正队似乎并不关心)

Answer 1:

你面临倒闭的问题。

看到这个问题: 什么是“封闭”在C#中?

试试这个。 它仅仅是相同的,但不完全因为你申报了“新的” 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 ;
}

我不觉得舒服的倒闭,我必须承认。



文章来源: C# Anonymous Function Scope in Unity3D