Dot-Net

繼承和 List<> 的問題

  • May 14, 2010

我有一個名為 Grouping 的抽像類。我有一個名為 GroupingNNA 的子類。

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

我有一個包含 GroupingNNA 類型項目的列表,但實際上被聲明為包含 Grouping 類型的項目。

List&lt;Grouping&gt; lstGroupings = new List&lt;Grouping&gt;();
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<Grouping> 返回的事實。

private List&lt;Grouping&gt; ApplyFilterSens(List&lt;Grouping&gt; lstGroupings, string fSens) {

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

 if (filtered != null) {
   **// Compiler doesn't like this now**
   return filtered.ToList&lt;Grouping&gt;();
 }
 else
   return new List&lt;Grouping&gt;();
 }

嘗試:

= from g in lstGroupings.OfType&lt;GroupingNNA&gt;()

這將跳過任何不是 type 的元素GroupingNNA,並使編譯器GroupingNNA用作g.

回應評論和編輯的問題。不,編譯器肯定不會對您更改的集合感到滿意,但您可以解決這個問題:

return new List&lt;Grouping&gt;(filtered.ToArray());

這依賴於 .NET 中的數組是協變/反變的這一事實,這允許編譯器將其GroupingNNA[]視為Grouping[]建構子。

此外,您不需要if (filtered != null)檢查,您將在 中獲得一個集合filtered,它可能不會產生任何元素,但filtered總是非null.

這意味著您的程式碼可以寫成:

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

甚至只是:

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

如果您放棄 linq 語法,甚至更短:

return new List&lt;Grouping&gt;((lstGroupings.OfType&lt;GroupingNNA&gt;()
   .Where(r =&gt; r.QASensitivity == fSens).ToArray());

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

return filtered.OfType&lt;Grouping&gt;().ToList();

這裡的不同方式之間不應該有任何大的性能差異,如果有疑問,請測量它,但我會選擇你認為最容易閱讀和理解的內容。

引用自:https://stackoverflow.com/questions/2830691