你如何在List <object> - &gt;之间进行转换? ObjectList和ObjectList - &gt; List(Object)使用泛型</object>

时间:2010-10-19 19:57:04

标签: c# generics

我发现我需要在许多类中编写相同的代码。代码与类型之间的转换有关。由于我不熟悉泛型,有人建议如何转换以下内容以使用泛型:

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;
    }
}

5 个答案:

答案 0 :(得分: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);

答案 1 :(得分: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的内容复制到新的List Container对象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();

答案 2 :(得分:0)

看起来你已经在使用泛型,所以也许我不理解这个问题。通用List<T>为您提供了列表内容的强类型作为Widgets,您将泛型类型T声明为Widget,因此除非有一些明确的原因需要WidgetList对象,该类(和WidgetManager)是多余的。

List<T>不是抽象的,所以你可以用Widget类完成这里显示的所有内容......然后当你需要一个Widgets列表时,你可以创建一个List<Widget>

答案 3 :(得分:0)

我假设您绝对需要一个自定义集合对象(WidgetList),但如果您不确定,请参阅答案底部的注释。在这种情况下,我建议如下:

  • WidgetList实施IList<Widget>而不是List<Widget>。否则,这是毫无意义的。您仍然可以使用List<Widget>作为实现。
  • 由于IList<Widget>也是IEnumerable<Widget>,因此您可以免费获得ToList<Widtget>() Linq扩展程序。
  • 另外,请确保WidgetList构造函数使用IEnumerable<Widget>而不是其他类中的函数。
  • AddRange(IEnumerable<Widget>)也很有用。

在旁注中,如果它只是WidgetList完全相同,则不需要List<Widget>。只需直接使用List<Widget>,它们就会提供集合对象提供的所有类型。我知道你会在框架库中找到很多这些集合对象,但它们之所以存在,是因为它们在泛型之前存在,或者因为它们在AddRemove上有其他行为。

答案 4 :(得分: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了解有一个Widgets集合这一事实。

也许不是?