在“ foreach”循环中使用LINQ仅运行一次

时间:2020-05-05 17:12:52

标签: c# list linq loops foreach

这是一个游戏。我正在尝试在加载游戏时将玩家的物品重新加载到他们的库存中。下面的“ itemStrings”是玩家保存游戏后所有项目名称的字符串列表。这是代码:

void Load(){ List<string> itemStrings = SaveLoad.Load<List<string>>("Inventory");

        foreach(string nameString in itemStrings)
        {
            loadReference = itemDatabase.itemsDatabaseList.Where(obj => obj.name == nameString).First();
            bool wasAdded = instance.Add(loadReference);
    }}

作为参考,itemDatabase是对类ItemDatabase的引用。存储游戏中的每个项目。 loadreference是一个称为Item的类,它在此Inventory类的开头声明。

我想做的是在数据库中搜索名称与itemStrings中的字符串匹配的项目,然后将该项目添加到播放器的清单中。此“ foreach”对于itemStrings列表中的第一个项目正常工作,但只运行一次。因此,无论以前保存了多少,它只会将一个项目加载到库存中。

2 个答案:

答案 0 :(得分:1)

之所以会这样,是因为您的loadReference是在其他位置定义的,因此您只是在更改指针(基本上每次都在先前加载的项目上进行复制)。

void Load()
{ 
    List<string> itemStrings = SaveLoad.Load<List<string>>("Inventory");

    foreach(string nameString in itemStrings)
    {
        var item = itemDatabase.itemsDatabaseList.Where(obj => obj.name == nameString).First();
        bool wasAdded = instance.Add(item);
    }
}

答案 1 :(得分:1)

我将重写您的内部查询,以仅在一个请求中返回所有值。

void Load()
{ 
  var inventory = SaveLoad.Load<List<string>>("Inventory")
    .Join(itemDatabase.itemDataList, name=>name, item=>item.name, (name,item)=>item);
  // Use one of the following three methods:
  instance.AddRange(inventory);
  // or if instance is just a List of items then...
  instance = inventory.ToList();
  // or if there is no AddRange, and instance is not just a List:
  foreach(var item in inventory)
  {
    instance.Add(item);
  }
}

或者,为自己创建一个GetInventory方法:

IEnumerable<Item> GetInventory()
{ 
  return SaveLoad.Load<List<string>>("Inventory")
    .Join(itemDatabase.itemDataList, name=>name, item=>item.name, (name,item)=>item);
}

然后,您可以在Load方法中使用它进行任何操作。