У меня есть несколько списков типов ArmorBase и WeaponBase, которые наследуют класс ItemBase. У меня также есть список, который представляет текущий выбранный список элементов.
public List<ItemBase> currentItemBasesList;
public List<ArmorBase> helmetBasesList;
public List<ArmorBase> chestplateBasesList;
public List<ArmorBase> shoulderguardsBasesList;
public List<ArmorBase> armguardsBasesList;
public List<ArmorBase> thighguardsBasesList;
public List<ArmorBase> bootsBasesList;
public List<ArmorBase> shieldBasesList;
public List<ArmorBase> capeBasesList;
public List<WeaponBase> weaponBasesList;
Но у меня возникли проблемы при назначении этих списков в список CurrentItemBasesList.
Моя первая мысль была:
currentItemBasesList = chestplateBasesList.Cast<ItemBase>().ToList();
Моя проблема в том, что таким образом я нарушаю референт на список нагрудников ListBasesList; Поэтому, если я удалю какой-либо элемент из списка currentItemBasesList, он не обновится в списке ChestplateBasesList.
Какие у меня варианты в этом случае? заранее спасибо
Вы не можете. Потому что у List<T>
есть методы, принимающие параметр T
, и другие, которые возвращают T
. Кастинг нарушит правила одного из этих методов. Иначе известно как дисперсия Learn.microsoft.com/en-us/dotnet/csharp/programming-guide/….
в идеале это должен быть просмотр основного списка
Cast a List<derivedType> into a List<baseType>
Не можете, так как список не является вариантом. Если бы это было возможно, вы могли бы добавить WeaponBase
к своему currentItemBasesList
, чтобы ваш chestplateBasesList
содержал оружие.
Вероятно, это признак того, что вам нужно пересмотреть все, что вы делаете. Трудно давать предложения, не понимая, что вы пытаетесь сделать.
В некоторых случаях достаточно просто использовать ковариантный интерфейс, например IReadOnlyList<T>
вместо List<T>
, но это не сработает, если вы планируете добавлять или удалять значения.
Или, возможно, вам нужен более высокий уровень абстракции, что-то вроде необщего IItemsView
, который предоставляет любую функциональность, необходимую для разных типов элементов, с разными реализациями для каждого типа элементов.
Или вы могли бы начать с того, что просто поместили все в один список и использовали фильтрацию для выбора определенного типа, поскольку IEnumerable оценивается лениво, helmets
будет отражать любые изменения в allItems
:
var allItems = new List<ItemBase>(){...};
var helmets = allItems.OfType<ArmorBase>().Where(armor => armor.Type == ArmorTypes.Helmet);
Используйте
ObservableCollection
илиBindingList
вместоList
. Подпишитесь на событиеCollectionChanged
илиListChanged
и реализуйте необходимую логику изменения второй коллекции.