2016-10-20 6 views
0

Unity3D에서 시뮬레이션 프로젝트를 만드는 동안 나는이 수수께끼 같은 행동을 보았습니다.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에서는 실패합니다. 마지막 값 ("3")을 1,2,3 대신에 3 번 인쇄하여 (버전 5.0).
내가 회피하기 위해 다양한 방법을 시도하고 다음이 뚜렷한 이유 일 : 다음 블록에 중요 부분을 변경 문제 해결 : 누군가가 대답 할 수있는 경우

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

기쁘게됩니다 (유니티 버그 수정 팀하지 않습니다 신경 써야 함)

답변

0

당신은 종결의 문제에 직면 해 있습니다. What are 'closures' in 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 ; 
} 

내가 폐쇄와 편안하지 않습니다, 내가 인정해야만한다.