2010-05-13 74 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