这是我的班级结构:
public class MainWindow
{
public List<FirstBar> FirstBars { get; set; }
public List<Foo> SelectedFoos { get; set; }
public MainWindow()
{
FirstBars = new List<FirstBar>();
SelectedFoos = new List<Foo>();
}
}
public abstract class Foo { public bool IsSelected { get; set; } }
public class FirstBar : Foo { public List<SecondBar> SecondBar { get; set; } }
public class SecondBar : Foo { }
...然后我想在这个条件下填写SelectedFoos
:
我想找到
FirstBar
的所有IsSelected==true
。如果我 找到一个FirstBar
IsSelected==false
,然后我找每个SecondBar
FirstBar
下的IsSelected==true
{/ 1}}。
所以,根据这个条件,我在MainWindow
的构造函数中进行集合初始化之后将它写到了某处:
/*assume below collections are already filled with some items.*/
SelectedFoos = FirstBars.Where(x => x.IsSelected).ToList(); //this is the error, below code is kinda irrelevant.
SelectedFoos.AddRange(FirstBars.Where(x => !x.IsSelected).SelectMany(x => x.SecondBars).Where(x => x.IsSelected).ToList();
但是,编辑说这是错误的/错误的:
无法隐式转换将
'...FirstBar>'
类型转换为'...Foo>'
然后,我试过了:
/*assume below collections are already filled with some items.*/
SelectedFoos = (List<Foo>)FirstBars.Where(x => x.IsSelected).ToList(); //this is the error, below code is kinda irrelevant.
SelectedFoos.AddRange((List<Foo>)FirstBars.Where(x => !x.IsSelected).SelectMany(x => x.SecondBars).Where(x => x.IsSelected).ToList();
之后,错误变为:
无法转换键入
'...FirstBar>'
至'...Foo>'
我的推理是(显然是错误的),因为他们(FirstBar
和SecondBar
)都有相同的父(Foo
),然后他们可以组合在其父级列表中(List<Foo>
)。
ThirdBar
(该集合位于SecondBar
)和FourthBar
内(此集合位于ThirdBar
内)。
任何人都可以解释是什么造成的吗?我觉得我对这个问题的继承有点遗失。
谢谢
答案 0 :(得分:5)
这个问题与这里的父母没有任何关系(而且你还没有进行加入) - 而且你的第二行甚至没有 。问题只是List<FirstBar>
不是List<Foo>
,即使每个FirstBar
都是Foo
。从.NET 4开始,使用通用协方差很容易解决这个问题:
SelectedFoos = FirstBars.Where(x => x.IsSelected).ToList<Foo>();
ToList
上的显式类型参数意味着它基本上等同于:
IEnumerable<FirstBar> tmp = Enumerable.Where<FirstBar>(FirstBars, x => x.IsSelected);
SelectedFoos = Enumerable.ToList<Foo>(tmp);
使用IEnumerable<FirstBar>
表达式可以转换为具有协方差的IEnumerable<Foo>
这一事实。