2010-05-13 59 views
7

我有一个叫做分组的抽象类。我有一个名为GroupingNNA的子类。继承问题和List <>

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

我有一个包含类型GroupingNNA的项目,但实际上是宣告包含类型分组的项目的列表。

List<Grouping> lstGroupings = new List<Grouping>(); 
lstGroupings.Add(
    new GroupingNNA { fName = "Joe" }); 
lstGroupings.Add(
    new GroupingNNA { fName = "Jane" }); 

问题: 下面的LINQ查询在我身上吹,因为一个事实,即lstGroupings被声明为List <分组>和FNAME是GroupingNNA的分组的属性,不是。

var results = from g in lstGroupings 
       where r.fName == "Jane" 
       select r; 

哦,这是一个编译器错误,而不是运行时错误。提前感谢您对这一个的任何帮助!

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

回答

6

尝试:

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

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

回复评论和编辑的问题。不,编译器将肯定不会高兴你更改后的集合,但你可以解决这个问题:

return new List<Grouping>(filtered.ToArray()); 

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

而且,你不需要if (filtered != null)检查,你会得到filtered集合,它可能只是不产生任何元素,但filtered永远是不可null

这意味着你的代码可以写为:如果你删除了LINQ语法

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

甚至更​​短:

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

甚至只是

return new List<Grouping>((lstGroupings.OfType<GroupingNNA>() 
    .Where(r => r.QASensitivity == fSens).ToArray()); 

注意你当然也可以使用OfType去另一种方式:

return filtered.OfType<Grouping>().ToList(); 

在这里不同的方法之间不应该有任何大的性能差异,如果有疑问,测量它,但我会用最容易阅读和理解的。

+0

谢谢!我现在更近一步了。但是,编译器现在不开心,因为我试图将匿名类型返回为列表< Grouping>。我会用一些更多的代码对我原来的帖子进行编辑,以便看到我在说什么。再次感谢。 – Jagd 2010-05-13 22:38:14

5

调用ToList<AnotherType>()正在将自己放回原来的位置 - 不支持泛型协方差/对立性 - 例如, List<Type>List<SubType>不兼容或可转换。

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

+0

.NET 2.x到3.5通用列表不变。这是为了你自己的利益。在.NET 4.0中寻找支持泛型中更宽松的输入 – 2010-05-14 02:02:53