2016-10-20 8 views
0

Unity3Dでシミュレーションプロジェクトを作成中に、この困惑している動作に遭遇しました。C#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では失敗します。最後の値( "3")を1,2,3の代わりに3回印刷することにより、バージョン5.0(バージョン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 ; 
} 

私は閉鎖と快適に感じることはありません、私は認めなければなりません。