Использование LINQ в 'foreach' l oop выполняется только один раз - PullRequest
2 голосов
/ 05 мая 2020

Это для игры. Я пытаюсь перезагрузить предметы игрока обратно в его инвентарь, когда он загружает игру. «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 ]

1 голос
/ 05 мая 2020

Я бы переписал ваш внутренний запрос, чтобы он просто возвращал все значения в одном запросе.

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

Тогда вы можете делать все вы хотите использовать его в своем методе загрузки.

1 голос
/ 05 мая 2020

Это происходит потому, что ваш 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);
    }
}
...