C# 将 Action 设置为等于 lambda 但让 lambda 在覆盖时保持可变
C# Set Action equal to a lambda but have the lambda keep it variable when overwritten
我真的不知道如何解释这个,但我已经尝试了一些东西,但它们不起作用。基本上我想对一个项目进行操作,该操作有点像项目功能。这是我的代码,它不是那么高级。
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();
}
}
我看到的问题是 i 变量没有保存在 lambda 中。
Action a = () => Console.WriteLine("Used Item " + i);
所以每当我调用 item[x].UseItem() 时,它都会在 for 循环内返回到 Action 声明,'uses' i 现在是 5.
如果你 运行 你的代码,你不会得到 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
得到 "updated" with Console.WriteLine("Used Item " + i);
with the current i
for loop, its last value is 11, so at the end of the loop you have
a = () => Console.WriteLine("Used Item " + 11);
对于每个 a
定义。
为了避免这个(常见的)错误,您需要按照 Rand Random 的建议实现一个临时变量:
var temp = i;
Action a = () => Console.WriteLine("Used Item " + temp);
我真的不知道如何解释这个,但我已经尝试了一些东西,但它们不起作用。基本上我想对一个项目进行操作,该操作有点像项目功能。这是我的代码,它不是那么高级。
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();
}
}
我看到的问题是 i 变量没有保存在 lambda 中。
Action a = () => Console.WriteLine("Used Item " + i);
所以每当我调用 item[x].UseItem() 时,它都会在 for 循环内返回到 Action 声明,'uses' i 现在是 5.
如果你 运行 你的代码,你不会得到 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
得到 "updated" with Console.WriteLine("Used Item " + i);
with the current i
for loop, its last value is 11, so at the end of the loop you have
a = () => Console.WriteLine("Used Item " + 11);
对于每个 a
定义。
为了避免这个(常见的)错误,您需要按照 Rand Random 的建议实现一个临时变量:
var temp = i;
Action a = () => Console.WriteLine("Used Item " + temp);