linq 如何在C#中更新列表中的一个元素而不更新所有元素?

roqulrg3  于 2022-12-06  发布在  C#
关注(0)|答案(5)|浏览(342)

我正在努力与一段代码,我想知道是否有人可以帮助我。
我的问题是:
我正在做一个游戏,我用字典创建了一个物品清单。我的字典TKey是物品名称,TValue是一个列表。每个物品都有一个布尔值“isEquiped”。

Dictionary<string, List<Item>> itemsInventory;

当装备一件物品时,我想检查一下玩家是否有足够的物品,以及是否可以装备。我用这个代码来做:

public void EquipWeapon(bool tog, Item item)
{
    if (tog == true)
    {
        if (player.weapon == false)
        {
            player.GetStatByName(item.StatAffectedName).AddModifier(item.StatAffectedValue, StatModifier.ModifierOrigins.Equipment, StatModifier.ModifierType.Flat, item.AssetName);
            GameManagerSingleton.Instance.PlayerData.itemsInventory.FirstOrDefault(x => x.Key == item.AssetName && x.Value.Any(x => x.isEquiped == false)).Value.FirstOrDefault().isEquiped = true;
        }
    }
    else
    {
        if (player.weapon == true)
        {
            player.GetStatByName(item.StatAffectedName).RemoveModifier(item.AssetName);
            GameManagerSingleton.Instance.PlayerData.itemsInventory.FirstOrDefault(x => x.Key == item.AssetName && x.Value.Any(x => x.isEquiped == true)).Value.FirstOrDefault().isEquiped = false;
        }
        player.weapon = false;
    }
    player.GetStatByName(item.StatAffectedName).GetValue();
}

我的代码的问题是它改变了列表中的所有项目而不仅仅是一个。有人能帮助我吗?

a2mppw5e

a2mppw5e1#

从您的注解 “如果我在调试器中更新,它也会更改所有项。" 看起来列表中的值是同一个对象。这强烈表明Itemclass(而不是struct)。
如果对象表示不同的示例,则需要在将它们添加到列表之前克隆它们。
Reference types (C# Reference)开始:
使用引用类型,两个变量可以引用同一个对象;因此,对一个变量的操作可能会影响另一个变量所引用的对象。
为了完整起见,您可以使用实值型别(可能是C#10提供的record struct):
对于值类型,每个变量都有自己的数据副本,对一个变量的操作不可能影响另一个变量(除了in、ref和out参数变量;参见in、ref和out参数修饰符)。

k4emjkb1

k4emjkb12#

使用linq查询出要更新的列表,然后单独更新列表中的项目。例如:How to update a single item of liist of objects using LINQ in C#

dy1byipe

dy1byipe3#

在我从false更改为true之后,不仅索引0处的项发生了更改,而且所有对象也发生了更改。

laawzig2

laawzig24#

当我创建播放器时,我创建的字典如下:

itemsInventory = new Dictionary<string, List<Item>>(),

当我创建列表时,它是这样的:

Instance.PlayerData.itemsInventory.Add("weapon", new List<Item>());
Instance.PlayerData.itemsInventory.Add("armour", new List<Item>());
Instance.PlayerData.itemsInventory.Add("shield", new List<Item>());
5ssjco0h

5ssjco0h5#

我的代码看起来像这样:

public void AddItemToInventory(Item? item, Ressource? ressource, int number = 1)
    {
        if (item != null)
        {
            int totalPrice = (item.Price * number);
            ressources.First(x => x.currency == item.Currency).amount -= totalPrice;
            DailyReportHandler.GetAndFillTodayReport().moneyForItems += totalPrice;
            if (itemsInventory.ContainsKey(item.AssetName))
            {
                for (int i = 0; i < number; i++)
                {
                    itemsInventory.FirstOrDefault(x => x.Key == item.AssetName).Value.Add(item);
                }
            }
            else
            {
                itemsInventory.Add(item.AssetName, new List<Item>());
                for (int i = 0; i < number; i++)
                {
                    itemsInventory.FirstOrDefault(x => x.Key == item.AssetName).Value.Add(item);
                }
            }
        }
        if (ressource != null)
        {
            int totalPrice = (ressource.price * number);
            ressources.First(x => x.currency == Currency.credit).amount -= totalPrice;
            DailyReportHandler.GetAndFillTodayReport().moneyForItems += totalPrice;
            GameManagerSingleton.Instance.PlayerData.AddResource(ressource.currency, number);
        }
    }

我把它改成了:

public void AddItemToInventory(Item? item, Ressource? ressource, int number = 1)
    {
        if (item != null)
        {
            int totalPrice = (item.Price * number);
            ressources.First(x => x.currency == item.Currency).amount -= totalPrice;
            DailyReportHandler.GetAndFillTodayReport().moneyForItems += totalPrice;
            if (itemsInventory.ContainsKey(item.AssetName))
            {
                for (int i = 0; i < number; i++)
                {
                    itemsInventory.FirstOrDefault(x => x.Key == item.AssetName).Value.Add(GenerateNewItem(item));
                }
            }
            else
            {
                itemsInventory.Add(item.AssetName, new List<Item>());
                for (int i = 0; i < number; i++)
                {
                    itemsInventory.FirstOrDefault(x => x.Key == item.AssetName).Value.Add(GenerateNewItem(item));
                }
            }
        }
        if (ressource != null)
        {
            int totalPrice = (ressource.price * number);
            ressources.First(x => x.currency == Currency.credit).amount -= totalPrice;
            DailyReportHandler.GetAndFillTodayReport().moneyForItems += totalPrice;
            GameManagerSingleton.Instance.PlayerData.AddResource(ressource.currency, number);
        }
    }

使用GenerateNewItem(item),如下所示:

public Item GenerateNewItem(Item item)
    {
        var newItem = new Item
        {
            AssetName = item.AssetName,
            Currency = item.Currency,
            DescriptionLocalizationKey = item.AssetName,
            isEquiped = false,
            itemType = item.itemType,
            NameLocalizationKey = item.NameLocalizationKey,
            Price = item.Price,
            ShortDescriptionLocalizationKey = item.ShortDescriptionLocalizationKey,
            StatAffectedName = item.StatAffectedName,
            StatAffectedValue = item.StatAffectedValue
        };
        return newItem;
    }

相关问题