Unity3D 中的 C# 匿名函数作用域 [英] C# Anonymous Function Scope in Unity3D

查看:40
本文介绍了Unity3D 中的 C# 匿名函数作用域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 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 控制台应用程序中运行良好,但在 Unity3D 上失败.(版本 5.0)通过打印最后一个值(3")3 次而不是 1,2,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# 中的闭包"?

试试这个.它只是相同,但不完全相同,因为您在循环中声明了一个新"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# 匿名函数作用域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆