C# Can';t在父母的同一集合下加入两个后代

C# Can';t在父母的同一集合下加入两个后代,c#,inheritance,collections,C#,Inheritance,Collections,这是我的班级结构: public class MainWindow { public List<FirstBar> FirstBars { get; set; } public List<Foo> SelectedFoos { get; set; } public MainWindow() { FirstBars = new List<FirstBar>(); SelectedFoos = ne

这是我的班级结构:

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 { }
但是,编辑说这是错误的:

无法将类型
“…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();
/*假设以下集合中已经填充了一些项目*/
SelectedFoos=(列表)FirstBars.Where(x=>x.IsSelected.ToList()//这就是错误,下面的代码有点不相关。
SelectedFoos.AddRange((列表)FirstBars.Where(x=>!x.IsSelected)。SelectMany(x=>x.SecondBars)。Where(x=>x.IsSelected)。ToList();
之后,错误更改为:

无法将类型
“…FirstBar>”
转换为
“…Foo>”

我的推理是(这显然是错误的),因为它们(
FirstBar
SecondBar
)都有一个相同的父项(
Foo
),所以它们可以组合在父项列表中(
list

顺便说一句,我知道如果我把它们分成不同的集合可以解决这个问题,但是最好有一个列表(因为在我真正的项目代码中,还有
ThirdBar
(这个集合在
SecondBar
中)和
FourthBar
(这个集合在
ThirdBar
中)

有人能解释这是什么原因吗?我觉得我有点迷失在继承的一些基本问题上了


谢谢你

这个问题与这里的父母无关(而且你也没有加入),甚至不在你的第二行。问题在于
列表
不是
列表
,即使每个
第一条
都是
Foo
。从.NET 4开始,使用通用协方差很容易解决这个问题:

SelectedFoos = FirstBars.Where(x => x.IsSelected).ToList<Foo>();

这是因为
IEnumerable
表达式可以转换为具有协方差的
IEnumerable

问题与这里的父级无关(而且您也没有进行连接)-它甚至不在你的第二行。问题在于
列表
不是
列表
,即使每个
FirstBar
都是
Foo
。从.NET 4开始,使用通用协方差很容易解决这一问题:

SelectedFoos = FirstBars.Where(x => x.IsSelected).ToList<Foo>();

这是因为
IEnumerable
表达式可以通过协方差转换为
IEnumerable

注意错误发生的位置非常重要-您的
AddRange
调用与此无关,因为编译时错误在前一行。已编辑。感谢您指出它。这真的很重要注意错误发生的位置很重要-您的
AddRange
调用与此无关,因为编译时错误在上一行。已编辑。感谢您指出。cr*p,我知道。我以前也尝试过
.ToList(List)
(我知道很傻)。是的,它不是字面上的“SQL的连接”.显然有点模棱两可。谢谢,我知道。我以前也试过
.ToList(List)
(我知道很傻)。是的,这不是字面上的“SQL的加入”。显然有点模棱两可。谢谢
IEnumerable<FirstBar> tmp = Enumerable.Where<FirstBar>(FirstBars, x => x.IsSelected);
SelectedFoos = Enumerable.ToList<Foo>(tmp);