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);