2017-06-23 15 views
0

我真的不知道该如何解释这一点,但我已经尝试了一些事情,他们不工作的时候。基本上我想要一个项目的行动,行动有点像项目功能。这是我的代码,它不是先进的。C#设置操作等于拉姆达但有拉姆达保持可变覆盖

class Item 
{ 
    private int itemCount; 
    private Action itemUsage; 
    string name; 

    //Item.Item() 
    public Item(string _name, Action _itemUsage, int _itemCount) 
    { 
     name = _name; 
     itemUsage = _itemUsage; 
     itemCount = _itemCount; 

     //laterInvokes itemUsage 
    } 

    //Item.UseItem 
    public void UseItem() 
    { 
     //TYPE:ACTION, is set in constructor 
     this.itemUsage(); 
    } 
} 

而且。

class Program 
{ 
    //Program.Main(string[] args) 
    public static void Main(string[] args) 
    { 
     Item[] items = new Item[11]; 

     //for every item in items; 
     for (int i = 0; i < items.Length; i++) 
     { 
      //How do i save 'a's lambda with out it coming back here? 
      Action a =() => Console.WriteLine("Used Item " + i); 
      items[i] = new Item("Item " + i, a, 1); 
     } 

     items[0].UseItem(); 
     items[3].UseItem(); 
     items[4].UseItem(); 
     items[7].UseItem(); 
     //Expect result; 
     //"Used Item 0" 
     //"Used Item 2" 
     //"Used Item 3" 
     //"Used Item 7" 

     //Actual Result 
     //"Used Item 5" 
     //"Used Item 5" 
     //"Used Item 5" 
     //"Used Item 5" 

     Console.ReadLine(); 
    } 


} 

问题,因为我可以看到它是我变量不保存在lambda中。

Action a =() => Console.WriteLine("Used Item " + i); 

所以每当我叫项[X] .UseItem()它可以追溯到里面的for循环操作的声明和“使用”的我有现在是5

+0

什么?再一次呢? –

+0

好的...我想我现在得到了你...尝试下面的''var temporaryInt = i;行动=()=> Console.WriteLine( “二手物品” + temporaryInt);“'' –

+0

谢谢你这只是那些时刻之一 –

回答

1

如果运行你的代码,你没有得到Used Item 5,但这:

Used Item 11 
Used Item 11 
Used Item 11 
Used Item 11 

,这是意料之中的,因为items.Length等于11

每次代码编译

Action a =() => Console.WriteLine("Used Item " + i); 

a被“更新”与Console.WriteLine("Used Item " + i);用的for循环当前i,其最后的值是11,所以在循环结束时,您有

a =() => Console.WriteLine("Used Item " + 11); 

为定义的每个a

为了避免这种(通用)的错误,你需要实现一个临时变量,如建议由兰德随机:

var temp = i; 
Action a =() => Console.WriteLine("Used Item " + temp);