.net - 继承和 List<> 的问题

标签 .net linq inheritance list

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

public class GroupingNNA : Grouping {
  // blah blah blah
}

我有一个包含 GroupingNNA 类型的项目的列表,但实际上声明为包含 Grouping 类型的项目。
List<Grouping> lstGroupings = new List<Grouping>();
lstGroupings.Add(
  new GroupingNNA { fName = "Joe" });
lstGroupings.Add(
  new GroupingNNA { fName = "Jane" });

问题:
由于 lstGroupings 被声明为 List< Grouping> 并且 fName 是 GroupingNNA 的一个属性,而不是 Grouping,因此下面的 LINQ 查询让我大吃一惊。
var results = from g in lstGroupings
              where r.fName == "Jane"
              select r;

哦,这是编译器错误,而不是运行时错误。在此先感谢您对这方面的任何帮助!

更多信息:
这是无法编译的实际方法。 OfType() 修复了 LINQ 查询,但编译器不喜欢我试图将匿名类型作为 List 返回的事实。
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>();
  }

最佳答案

尝试:

= from g in lstGroupings.OfType<GroupingNNA>()

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

回应评论和编辑的问题。不,编译器肯定不会对您更改的集合感到满意,但您可以解决这个问题:
return new List<Grouping>(filtered.ToArray());

这依赖于这样一个事实,即 .NET 中的数组是协变/逆变的,这允许编译器处理 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());

甚至只是:
return new List<Grouping>((from r in lstGroupings.OfType<GroupingNNA>()
                           where r.QASensitivity == fSens
                           select r).ToArray());

如果您删除 linq 语法,甚至更短:
return new List<Grouping>((lstGroupings.OfType<GroupingNNA>()
    .Where(r => r.QASensitivity == fSens).ToArray());

请注意,您当然可以使用 OfType也可以走另一条路:
return filtered.OfType<Grouping>().ToList();

这里的不同方式之间不应该有任何大的性能差异,如果有疑问,请对其进行测量,但我会采用您认为最容易阅读和理解的方法。

关于.net - 继承和 List<> 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2830691/

相关文章:

c# - 使用 Linq 搜索

C++ 结合静态和动态多态性来创建 "Hyper Polymorphism"?

java - 为什么 java.awt.Image 不被视为 java.awt.Component?

python - 当它似乎是从一个实例继承时,如何将类放在它自己的文件中?

c++ - Opencv C++ 在阈值图像中寻找运动

c# - 使用模板和字段将新页面添加到 iTextSharp 的 PdfStamper

c# - 如何使用 string.split 对具有特定格式的字符串列表进行排序?

c# - 当列表索引超出范围时,Linq 获取第一个或最后一个元素

c# - 静态属性最终会出现在 gen2 中吗?

asp.net - 无效的 resx 文件。找不到文件 ..\..\My Project\Resources.resx