C#返回通用列表/ IEnumerable,它是如何工作的?

时间:2012-10-02 10:41:39

标签: c# list generics ienumerable

我有一个方法可以返回一个汽车列表(IEnumerable)..

(适用于返回类型IEnumerable<Car>List<Car>):

public IEnumerable<Car> GetCars(string xml)
{
    var myResultList;

     XElement doc = XElement.Parse(xml);
     myResultList = doc.Descendants().Descendants("dict").Select(
     x => new Employee
     {
         Id = x.Elements("string").ElementAt(0).Value,
         Prename = x.Elements("string").ElementAt(1).Value,
         Name = x.Elements("string").ElementAt(2).Value,
         Initials = x.Elements("string").ElementAt(3).Value
    }
    );

    IEnumerable<Car> enumerable = myResultList;
    return enumerable;

    //---

    //or as a List if it's better?
    List<Car> asList = enumerable.ToList();
    //then: return asList
}

现在我想将此方法泛型。 每个IEnumerable类型/或列表类型都应该可以。

这样的东西 - 那只是伪代码,因为我不知道它是如何工作的;

public IEnumerable<T> GetData(string xml)
{
    var myResultList;

    //...myResultList.. will be filled here (unnecessary) 

    IEnumerable<T> enumerable = myResultList;
    return enumerable;

    //---

    //or as a List if it's better?
    List<T> asList = enumerable.ToList();
    //then: return asList
}

我希望我的问题足够明确。想象一下你会有另一种类型,比如 House 而不是 Car ,但你想为每种类型使用相同的方法

我怎样才能实现这一目标?帮助将不胜感激。

编辑:

添加了填写&#34; myResultsList&#34;

的代码

编辑2: 2 XML应该使用相同的方法:

 <plist version="1.0">
  <dict>
    <key>DataType</key>
    <string>Employee</string>
    <key>8000</key>
    <dict>
      <key>MitarbeiterNo</key>
      <string>8000</string>
      <key>Vorname</key>
      <string>Walter</string>
      <key>Name</key>
      <string>Walter Lohner Stans</string>
      <key>Initialien</key>
      <string>MAL</string>
    </dict>
    <key>8001</key>
    <dict>
      <key>MitarbeiterNo</key>
      <string>8001</string>
      <key>Vorname</key>
      <string>Motorrad</string>
      <key>Name</key>
      <string> Meierskappel</string>
      <key>Initialien</key>
      <string>MAM</string>
    </dict>
    <key>8004</key>
    <dict>
      <key>MitarbeiterNo</key>
      <string>8004</string>
      <key>Vorname</key>
      <string>Hanspeter</string>
      <key>Name</key>
      <string>Altenbürger AG  Horgen</string>
      <key>Initialien</key>
      <string>FH</string>
    </dict>
  </dict>
</plist>

 <plist version="1.0">
  <dict>
    <key>DataType</key>
    <string>Agent</string>
    <key>7000</key>
    <dict>
      <key>AgentNo</key>
      <string>7000</string>
      <key>Initialien</key>
      <string>VW</string>
      <key>Namen</key>
      <string>Walter Gnos Vertretungen  Vevey</string>
    </dict>
    <key>7001</key>
    <dict>
      <key>AgentNo</key>
      <string>7001</string>
      <key>Namen</key>
      <string>Miller GmbH Bern</string>
    </dict>
    <key>7002</key>
    <dict>
      <key>AgentNo</key>
      <string>7002</string>
      <key>Initialien</key>
      <string>MAL</string>
      <key>Namen</key>
      <string>Walter Lohner Stans</string>
    </dict>
  </dict>
</plist>

2 个答案:

答案 0 :(得分:4)

您唯一缺少的是<T>

public IEnumerable<T> GetData<T>(string xml)

然后你把它称为:

var data = obj.GetData<House>(xml);

<House>告诉GetData T对该通话的影响。请注意,在GetData<T>内,您可以使用typeof(T)来获取Type,如果您使用XmlSerializer或类似的进行反序列化,这可能是必要的。

请注意,在某些情况下,使用泛型可能非常方便,而其他一些实际上可能会导致问题 - 所以您可能 想要考虑是否使用可能不合适:

public IEnumerable GetData(Type type, string xml)

即。将Type作为常规参数传递。如果你在反射中做了很多工作,那么这可能很有用,因为泛型变得棘手。但要强调的是:通用和非通用解决方案都是合理有效的。

答案 1 :(得分:0)

以下是您要尝试的示例。您可以将此代码粘贴到控制台应用程序中:

using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace Stackoverflow
{
    public class Foo
    {
        public int Id { get; set; }
        public Bar Bar { get; set; }
    }

    public class Bar { }

    class Program
    {
        private static void Main()
        {
            var foos = new List<Foo>
                           {
                               new Foo { Id =1, Bar = new Bar()},
                               new Foo { Id =2, Bar = null},
                               new Foo { Id =3, Bar = new Bar()},
                               new Foo { Id =4, Bar = null},
                           };

            var xml = ToXml(foos);

            var result = GetData<List<Foo>>(xml);
        }

        private static string ToXml(List<Foo> foos)
        {
            XmlSerializer ser = new XmlSerializer(foos.GetType());
            StringBuilder sb = new StringBuilder();
            StringWriter writer = new StringWriter(sb);
            ser.Serialize(writer, foos);

            string xml = sb.ToString();
            return xml;
        }

        public static T GetData<T>(string xml)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);

            XmlNodeReader reader = new XmlNodeReader(doc.DocumentElement);
            XmlSerializer ser = new XmlSerializer(typeof(T));
            object obj = ser.Deserialize(reader);

            T result = (T)obj;

            return result;
        }
    }
}