c# - 不能将 2 个后代加入其 parent 的同一集合下

标签 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 = 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在这种情况下/在这种情况下:

I want to find all FirstBars which IsSelected==true. And if I found a FirstBar which IsSelected==false, I then look for each SecondBar under FirstBar which IsSelected==true.

因此,基于该条件,我在 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();

但是,编辑说这是错误的:

Cannot implicitly convert type '...FirstBar>' to '...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();

之后错误变为:

Cannot convert type '...FirstBar>' to '...Foo>'

我的推理是(这在某种程度上显然是错误的),因为它们( FirstBarSecondBar )都有相同的父级( Foo ),那么它们可以组合在一个列表中他们的 parent ( List<Foo> )。

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

谁能解释一下这是什么原因造成的?我觉得我有点迷失了这个问题的一些继承基础。

谢谢

最佳答案

这个问题与这里的 parent 无关(而且你也没有进行连接)——而且它甚至不在你的第二行中。。问题只是一个 List<FirstBar>不是 List<Foo> ,即使每个 FirstBarFoo .从 .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>具有协方差。

关于c# - 不能将 2 个后代加入其 parent 的同一集合下,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26009608/

相关文章:

c# - foreach计算多个数组

python - 向父类中的函数添加条件更好,还是为每个子类定义单独的函数更好?

c++ - 不确定在尝试扩展我的堆栈功能时是否使用继承

java - 如何将所有枚举值正确插入到哈希集中?

java - 按字母顺序对复杂对象的数组列表进行排序

java - 如何在 Java 7 中使用集合文字?

c# - .NET Core 中的 win/any 运行时是什么意思

c# - DateTime.ParseExact() 比 DateTime.Parse() 快吗

c# - 在 AspNetCore OpenIdConnect 上设置 redirect_uri

c++ - error : no match for 'operator=' . 尝试从基类继承并从基类初始化?