继承问题和List <>

Jag*_*agd 7 .net linq inheritance list

我有一个名为Grouping的抽象类.我有一个名为GroupingNNA的子类.

public class GroupingNNA : Grouping {
  // blah blah blah
}
Run Code Online (Sandbox Code Playgroud)

我有一个List包含GroupingNNA类型的项目,但实际上声明包含类型分组的项目.

List<Grouping> lstGroupings = new List<Grouping>();
lstGroupings.Add(
  new GroupingNNA { fName = "Joe" });
lstGroupings.Add(
  new GroupingNNA { fName = "Jane" });
Run Code Online (Sandbox Code Playgroud)

问题: 由于lstGroupings被声明为List <Grouping>而fName是GroupingNNA的属性而不是Grouping,因此以下LINQ查询对我不利.

var results = from g in lstGroupings
              where r.fName == "Jane"
              select r;
Run Code Online (Sandbox Code Playgroud)

哦,这是一个编译器错误,而不是运行时错误.在此预先感谢任何帮助!

更多信息: 这是不能编译的实际方法.OfType()修复了LINQ查询,但编译器不喜欢我试图将匿名类型作为List <Grouping>返回的事实.

private List<Grouping> ApplyFilterSens(List<Grouping> lstGroupings, string fSens) {

  // This works now! Thanks @Lasse
  var filtered = from r in lstGroupings.OfType<GroupingNNA>()
                 where r.QASensitivity == fSens
                 select r;

  if (filtered != null) {
    **// Compiler doesn't like this now**
    return filtered.ToList<Grouping>();
  }
  else
    return new List<Grouping>();
  }
Run Code Online (Sandbox Code Playgroud)

ang*_*son 6

尝试:

= from g in lstGroupings.OfType<GroupingNNA>()
Run Code Online (Sandbox Code Playgroud)

这将跳过任何非类型的元素GroupingNNA,并使编译器GroupingNNA用作类型g.

回应评论和编辑问题.不,编译器肯定不会对您更改的集合感到满意,但您可以解决这个问题:

return new List<Grouping>(filtered.ToArray());
Run Code Online (Sandbox Code Playgroud)

这依赖于一个事实,即在.NET数组是CO /禁忌变种,它允许编译器把GroupingNNA[]作为Grouping[]的构造函数.

此外,您不需要if (filtered != null)检查,您将获得一个集合filtered,它可能不会生成任何元素,但filtered始终是非元素null.

这意味着您的代码可以写成:

var filtered = from r in lstGroupings.OfType<GroupingNNA>()
               where r.QASensitivity == fSens
               select r;
return new List<Grouping>(filtered.ToArray());
Run Code Online (Sandbox Code Playgroud)

甚至只是:

return new List<Grouping>((from r in lstGroupings.OfType<GroupingNNA>()
                           where r.QASensitivity == fSens
                           select r).ToArray());
Run Code Online (Sandbox Code Playgroud)

如果删除linq语法,甚至更短:

return new List<Grouping>((lstGroupings.OfType<GroupingNNA>()
    .Where(r => r.QASensitivity == fSens).ToArray());
Run Code Online (Sandbox Code Playgroud)

请注意,您当然也可以使用OfType其他方式:

return filtered.OfType<Grouping>().ToList();
Run Code Online (Sandbox Code Playgroud)

这里的不同方式之间不应该存在任何重大的性能差异,如果有疑问,请测量它,但我会选择您最容易阅读和理解的内容.


Rex*_*x M 5

呼叫ToList<AnotherType>()使自己回到以前的同一条船上 - 不支持通用协方差/逆变 - 例如List<Type>,不兼容或可转换为/来自List<SubType>.

你需要使用filtered.OfType<Grouping>().ToList();- 第一个让你回到一个IEnumerable<Grouping>而不是一个IEnumerable<GroupingNNA>,然后ToList只是转换IEnumerable为一个List相同的泛型类型.