T 到对象有效,但列表<T>到列表<Object>根本不起作用



欢迎使用以下代码。我知道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(。

最新更新