2013-03-24 45 views
7

我想創建一個方法,它返回用戶想要的任何類型的列表。要做到這一點,我使用的泛型,我不太熟悉,所以這個問題可能很明顯。問題是,這個代碼不工作,並引發錯誤消息Cannot convert type Systems.Collections.Generic.List<CatalogueLibrary.Categories.Brand> to Systems.Collection.Generic.List<T>可以使用IList但不是列表中的泛型方法

private List<T> ConvertToList<T>(Category cat) 
{    
    switch (cat) 
    { 
     case Category.Brands: 
      return (List<T>)collection.Brands.ToList<Brand>(); 

    } 
    ... 
} 

但是,如果使用IList代替,沒有錯誤。

private IList<T> ConvertToList<T>(Category cat) 
{    
    switch (cat) 
    { 
     case Category.Brands: 
      return (IList<T>)collection.Brands.ToList<Brand>(); 

    } 
    ... 
} 

爲什麼在這種情況下可以使用IList而不是List? collection.Brands從第三方庫中返回一個BrandCollection類型,所以我不知道它是如何創建的。難道BrandCollection可能來自IList(只是猜測它確實),所以它可以轉換爲它,但不是正常的列表?

+0

你應該把類型約束放在那裏!你不能只是圍繞着鑄造東西。 – antonijn 2013-03-24 20:17:17

+3

你確定你的第二個例子不是'return(IList )collection.Brands.ToList ();'? – Matthew 2013-03-24 20:18:13

+0

我打算在這個工作後看看。我對泛型有點新,所以我認爲在後面的情況下它會破壞別的東西:D約束條件是'T:品牌'(和其他類別)嗎? – XSL 2013-03-24 20:18:30

回答

9

由於T沒有限制,因此只能在編譯時轉換爲object。強制轉換爲接口類型不被編譯器檢查,因爲理論上可能會創建一個新類,該類實現了IList<object>並繼承了List<Brand>。然而,轉換到List<T>將失敗,因爲已知不能創建繼承List<object>List<Brand>的類。然而,就你而言,你知道T類型是通過你的switch聲明並希望強制演員。

private List<T> ConvertToList<T>(Category cat) 
{    
    switch (cat) 
    { 
     case Category.Brands: 
      return (List<T>)(object)collection.Brands.ToList<Brand>(); 
    } 
} 

更大的設計問題在這裏,雖然是仿製藥是不是最好的選擇,當你有已知類型的用於T離散列表:要做到這一點,通過object首先如下投。當T既可以是任何東西,也可以限制爲基本類型或接口時,泛型更好。在這裏,你會離開只是寫一個單獨的方法switch語句的每個分支更好:

private List<Brand> ConvertToBrandList() 
{ 
    return collection.Brands.ToList<Brand>(); 
} 

如果沒有這個,你只有很少類型安全。如果有人用ConvertToList<int>(Category.Brands)打電話給你的方法怎麼辦?

+0

感謝您的解釋。儘管'object'方法起作用了,我會去找個別的方法路線。我只是發現它是一個封閉的類,我無法將其限制爲「品牌」。 – XSL 2013-03-24 20:50:01

+0

+1。我認爲真正的原因是由於C#參考6.2.4:「明確的參考轉換是......\t從*任何類類型S *到*任何接口類型T *,只要S不密封並且提供S不執行T. – 2013-03-24 20:51:50

相關問題