我想做这样的事情:
List<Child> childList = new List<Child>();
...
List<Parent> parentList = childList;
但是,因为parentList是Child的祖先的 List ,而不是直接的祖先,所以我无法做到这一点。是否有解决方法(除了单独添加每个元素)?
答案 0 :(得分:67)
答案 1 :(得分:57)
不允许直接进行转换,因为无法使其类型安全。如果你有长颈鹿的名单,并将它投入到动物名单中,那么你可以将老虎放入长颈鹿名单中!编译器不会阻止你,因为当然老虎可能会进入动物列表。编译器可以阻止你的唯一地方是不安全的转换。
在C#4中,我们将支持SAFE接口和使用引用类型参数化的委托类型的协方差和逆变。有关详细信息,请参见此处:
http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx
答案 2 :(得分:4)
早在2009年,Eric就嘲笑我们C#4会有所改变。那么我们今天在哪里?
我的答案中使用的类可以在底部找到。为了更容易理解,我们将Mammal
类用作“父级”,将Cat
和Dog
类用作“子级”。猫和狗都是哺乳动物,但猫不是狗,狗不是猫。
这仍然不合法,不能是:
List<Cat> cats = new List<Cat>();
List<Mammal> mammals = cats;
为什么不呢?猫是哺乳动物,为什么我们不能将猫列表分配到List<Mammal>
?
因为,如果允许我们在List<Cat>
变量中存储对List<Mammal>
的引用,那么我们就可以编译以下代码来将狗添加到猫列表中:
mammals.Add(new Dog());
我们绝不允许这样!请注意,mammals
只是对cats
的引用。 Dog
并非来自Cat
,并且没有商家位于Cat
个对象的列表中。
Starting with .NET Framework 4,几个通用接口具有使用C#4中引入的out
Generic Modifier关键字声明的协变类型参数。这些接口中的IEnumerable<T>
当然是由{{1}实现的}}
这意味着我们可以现在将List<T>
投放到List<Cat>
:
IEnumerable<Mammal>
我们无法向IEnumerable<Mammal> mammalsEnumerable = cats;
添加新的Dog
,因为mammalsEnumerable
是“只读”界面,即它没有IEnumerable<out T>
方法,但我们 现在可以使用Add()
,只要cats
可以消费。例如,我们可以将IEnumerable<Mammal>
与mammalsEnumerable
连接起来以返回新序列:
List<Dog>
班级定义:
void Main()
{
List<Cat> cats = new List<Cat> { new Cat() };
IEnumerable<Mammal> mammalsEnumerable =
AddDogs(cats); // AddDogs() takes an IEnumerable<Mammal>
Console.WriteLine(mammalsEnumerable.Count()); // Output: 3. One cat, two dogs.
}
public IEnumerable<Mammal> AddDogs(IEnumerable<Mammal> parentSequence)
{
List<Dog> dogs = new List<Dog> { new Dog(), new Dog() };
return parentSequence.Concat(dogs);
}
答案 3 :(得分:0)
var result = List.And(x => x.Parent.All(b => b.ParentId == value));
答案 4 :(得分:-2)
您可以使用应用扩展方法的Linq方法,即:
List<Parent> parentList = childList.Cast<Parent>().ToList();