2010-10-19 34 views
0

我發現我需要在許多類中編寫相同的代碼。代碼與類型之間的轉換有關。由於我不熟悉的仿製藥,會有人建議如何以下步驟轉換到使用泛型:你將如何轉換列表<Object> - > ObjectList和ObjectList - >列表(對象)使用泛型

public class WidgetList : List<Widget> { } 

public class Widget 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 

    public Widget() { } 

    public Widget(int Id, string Name) 
    { 
     this.Id = Id; 
     this.Name = Name; 
    } 
} 

public class WidgetManager 
{ 
    public static List<Widget> ToListType(WidgetList list) 
    { 
     return list.ToList<Widget>(); 
    } 

    public static WidgetList ToTypeList(List<Widget> list) 
    { 
     WidgetList typeList = new WidgetList(); 
     foreach (Widget item in list) 
     { 
      typeList.Add(w); 
     } 

     return typeList; 
    } 
} 
+2

也許我誤解你的意圖,但什麼是一個巡航能力型的widgetList的地步? WidgetList是List 的空白子類,因此它唯一的真正目的是給列表指定一個特定的名稱。 – Stephan 2010-10-19 20:00:31

+0

我不確定你爲什麼要分類一個通用的'List',如果你沒有添加功能。你有分類的理由嗎?你爲什麼不能在'List '上操作? – linuxuser27 2010-10-19 20:00:44

+0

這是一種模式...幫助我們成爲懶惰的編碼器。我們沒有向WidgetList添加任何屬性。它只是一個集合。我們的大部分代碼都使用該列表。我們需要列表的唯一時間是使用linq過濾列表中包含的數據。這就是爲什麼我想編寫通用轉換方法。 – sme 2010-10-19 20:33:18

回答

1

這裏的魔力:

添加一個擴展的IEnumerable:

public static class IEnumerableExtensions 
{ 
    public static T2 ToListContainer<T1, T2>(this IEnumerable<T1> list) where T2: List<T1>, new() 
    { 
     T2 listContainer = new T2(); 
     listContainer.AddRange(list); 
     return listContainer; 
    } 

} 

以上將IEnumerable的列表T1中的內容複製到新的列表容器對象T2和返回。

只是爲了測試:

WidgetList widgets = new WidgetList(); 

widgets.Add(new Widget(1, "Dog 1")); 
widgets.Add(new Widget(2, "Dog 2")); 
widgets.Add(new Widget(3, "Dog 3")); 
widgets.Add(new Widget(4, "Cat 1")); 
widgets.Add(new Widget(5, "Dog 2")); 
widgets.Add(new Widget(6, "Dog 3")); 


widgets = (from w in widgets 
      where w.Name.Contains("1") 
      select w).ToListContainer<Widget, WidgetList>(); 

int c = widgets.Count(); 
0

看起來你已經在使用仿製藥,所以也許我不理解的問題。通用List<T>爲您提供了在聲明泛型類型T爲Widget的地方作爲Widgets的列表內容的強類型,所以除非有一些明確的理由說明爲什麼需要WidgetList對象,該類(和WidgetManager)是多餘的。

List<T>不是抽象的,這樣你就可以實現這個目標是在這裏顯示只有Widget類......那麼,當你需要一個Widget列表,你可以創建一個List<Widget>一切。

0

我會假設你絕對需要一個自定義集合對象(WidgetList),但如果你不確定,請在答案底部看到註釋。在這種情況下,我會建議如下:

  • WidgetList實施IList<Widget>,而不是從List<Widget>獲得。否則,這是毫無意義的。您仍然可以使用List<Widget>作爲實現。
  • 由於IList<Widget>也是IEnumerable<Widget>,您將有ToList<Widtget>(),與Linq擴展免費。
  • 此外,請確保你有一個WidgetList構造函數採取IEnumerable<Widget>而不是一個不同的類中的功能。
  • AddRange(IEnumerable<Widget>)也非常有用。

在一個側面說明,如果它的作用是完全一樣的一個List<Widget>你不需要WidgetList。只需直接使用List<Widget>,它們提供集合對象提供的所有輸入。我知道你會在框架庫中找到很多這些集合對象,但是它們在那裏或者是因爲它們在泛型之前存在,或者因爲它們在AddRemove上有其他行爲。

2

那麼,你的代碼片段使用泛型。

也許你的印象是泛型在某種意義上是抽象的,必須被實現爲任何用途,但是如果這種情況你是(很高興!)錯誤的。

只需刪除您的WidgetManagerWidgetList類。您可以使用List<Widget>而不會有任何額外的複雜性。例如:

var widgets = new List<Widget>(); 

widgets.Add(new Widget(42, "foo")); 
widgets.Add(new Widget(43, "bar")); 

foreach (var widget in widgets) 
    Console.WriteLine("{0}: {1}", widget.Id, widget.Name); 
0

只是澄清了這個問題 - 因爲我也在sme的團隊。究其原因,強類型的widgetList是因爲我們使用的XML解串器控件列表從XML從我們的數據庫通過轉換:

<Widgets> 
<Widget> 
    <Id>1</Id> 
    <Name>Kitten Kung-Foo</Id> 
</Widget> 
<Widget> 
    <Id>2</Id> 
    <Name>Puppy Punches</Name> 
</Widget> 
<Widgets> 

所以這裏用XML再次是相同的代碼屬性:

[XmlType("Widgets"), Serializable] 
public class WidgetList : List<Widget> { } 

[XmlType("Widget"), Serializable] 
public class Widget 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 

    public Widget() { } 

    public Widget(int Id, string Name) 
    { 
     this.Id = Id; 
     this.Name = Name; 
    } 
} 

我很確定我們需要WidgetList,以便Deserializer能夠接收到有一個Widget集合的事實。

也許不是?

相關問題