这可能相当明显,但我似乎无法得到它。对于一个相当复杂的重构(a.k.a hack),我需要能够根据一些标志交换出“类型”列表。为了使交换更容易并防止嵌套函数的“下游”更改,我决定做这样的事情:
List<Object> myList = new List<Tuple<string, bool>>();
基于某些标志我想改为:
List<Object> myList= new List<MyObject>();
这样我就可以使用myList
,而不会在使用列表的方法中进行太多更改。在大多数情况下,他们只是在列表中添加元素而不是从中读取,因此这种“黑客”会非常方便。
但是,我似乎无法做到这一点,因为C#编译器抱怨它无法从System.Tuple
转换为Object
。我真的错过了什么?
答案 0 :(得分:4)
List<T>
不是covariant type。
如果是这样,一个问题是类可能根据其指定的泛型类型进行不同的操作。例如,想象一下:
class Foo<T>
{
public bool FooBar()
{
return typeof(T).Name.ToLower() == "object";
}
}
现在,如果您允许Foo<string>
投放到Foo<object>
,那么FooBar()
会在投放后返回什么内容?
有三种解决方案:
List<object>
并向其添加Tuple<string, bool>
类型实例。IList
。但是,这有潜在的缺点,因为您期望List<T>
和不同的类实现IList
可能会被传递。
abstract class Animal { }
class Cat : Animal { }
class Dog : Animal { }
public List<Animal> animals = new List<Animal>();
然后,您可以使用.Add()
或Cat
个对象作为参数调用Dog
和其他方法,使用is
检查每个条目的类型,并完全避免强制转换。这是否合适取决于您的类型以及它们如何相互作用。
答案 1 :(得分:1)
List<T>
不是covariant。你不能这样做。如果需要,创建一个List<object>
并用所有元素填充它。虽然我并没有真正看到使用带有object
的强类型通用列表的优势。