欢迎使用以下代码。我知道T将始终是来自基类"的类型;项目";。但我无法将列表转换为项目。对于T项,它是有效的。
private List<Item> activeItemList;
private Item activeItem;
public void StartBuildingSystem<T>(List<T> itemList, T item, int count, string name) where T : Item
{
UiPlacementActivate(itemList, item,count);
PlacingAreas(GetActiveBluePrint(name), GetActiveType(itemList, name));
activeBuildingType = GetActiveBuildingType(name);
activeItem = item;
//activeItemList = itemList;//
}
////中的代码不起作用,因为我无法将列表T强制转换为列表项。有更好的方法吗?如果我知道传入列表将总是来自基类";项目";但它来自不同的库存(Cooling,Secruity,…(,或者有没有一种方法可以像T项目到项目一样,将列表简单地转换为项目列表。
不能在各种类型的列表之间进行强制转换,因为List<T>
是不变的。请参阅仍然对协方差感到困惑的更多信息(或查看Stackoverflow上的3000个问题(。
您可以转换列表(通过一次转换一个列表项(,而不是强制转换。所以不是
activeItemList = itemList;
使用
activeItemList = itemList.Select( x => (Item)x ).ToList();
如果您可以在代码中进行以下更改,它将允许协方差:
private IEnumerable<Item> activeItemList; // previously List<Item>
private Item activeItem;
public void StartBuildingSystem<T>(List<T> itemList, T item, int count, string name) where T : Item
{
UiPlacementActivate(itemList, item,count);
PlacingAreas(GetActiveBluePrint(name), GetActiveType(itemList, name));
activeBuildingType = GetActiveBuildingType(name);
activeItem = item;
activeItemList = itemList; //it will now work
}
可变集合无法实现差异。要了解原因,请参阅以下基于代码的示例:
private List<Fruit> currentFruitList;
private Fruit currentFruit;
public void StartBuildingSystem<T>(List<T> fruitList, T fruit) where T : Fruit
{
currentFruit = fruit;
currentFruitList = fruitList;
}
让我们想象一下,上面的代码会编译(不会编译(。现在想象你这样做:
List<Apple> apples = new();
Apple apple = new();
StartBuildingSystem(apples, apple);
Orange orange = new();
currentFruit = orange; //fine!
currentFruitList.Add(new Orange()); //this is a problem!
然而,不可变集合可以处理此问题。为了扩展这个例子,如果您将List<Fruit>
更改为IEnumerable<Fruit>
,那么一切都会编译得很好,因为您不会意外地将橙色添加到IEnumerable<Apple>
这是微软提供的关于这个主题的更好的文章之一。
John的答案看起来是可行的,但这是一个替代方案:
// add "using System.Linq;" beforehand
activeItemList = itemList.Cast<Item>().ToList();
其他答案也解释了这一点,但基本上,activeItemList
不能被分配给Item
的严格子类型(比如BlueItem
(的列表,因为这样,这个列表将更"复杂";有限的";并且不能处理Item
的其他非重叠亚型(例如RedItem
(。