为什么我不能实例化List与List>

本文关键字:List Tuple string bool Object 不能 实例化 为什么 | 更新日期: 2023-09-27 18:08:06

这可能是相当明显的,但我似乎不能得到它。对于一个相当复杂的重构(又名hack),我需要能够根据一些标志交换出列表的"类型"。为了使交换更容易,并防止嵌套函数的"下游"更改,我决定这样做:

List<Object> myList = new List<Tuple<string, bool>>();

基于某些标志,我想这样做:

List<Object> myList= new List<MyObject>();

这样我就可以几乎原样使用myList,而不需要对使用列表的方法进行太多更改。在大多数情况下,它们只向列表中添加元素,而不从列表中读取元素,因此这种"hack"将相当方便。

然而,我似乎真的不能这样做,因为c#编译器抱怨它不能从System.Tuple转换到Object。我到底错过了什么?

为什么我不能实例化List<Object>与List<Tuple<string, bool>>

List<T>不是协变类型

如果是的话,一个问题是类可能根据它们被分配的泛型不同而操作不同。例如,想象一下:
class Foo<T>
{
    public bool FooBar()
    {
        return typeof(T).Name.ToLower() == "object";
    }
}

现在,如果允许将Foo<string>强制转换为Foo<object>,那么强制转换后FooBar()返回什么?

有三个解决方案:

  1. 只使用List<object>并添加Tuple<string, bool>类型的实例。
  2. 转换为IList。但是,这有潜在的缺点,因为您期望传递List<T>和实现IList不同的类。
  3. 将接受的列表类型转换为层次结构,并使用基本类型的列表,例如:

.

abstract class Animal { }
class Cat : Animal { }
class Dog : Animal { }
public List<Animal> animals = new List<Animal>();

那么您可以调用.Add()和其他方法,以CatDog对象作为参数,用is检查每个条目的类型,并完全避免强制转换。但是,这是否合适取决于您的类型以及它们如何相互作用。

List<T>不是协变的。你不能这么做。如果你想,创建一个List<object>,并填充所有的元素。虽然我真的没有看到在object中使用强类型泛型列表的优势。

相关文章: