如何迭代IEnumerable <ienumerable <t>&gt;将数据序列化为CSV时

时间:2015-09-23 01:03:37

标签: c# .net list generics ienumerable

我正在编写一个C#类,用于将数据序列化为CSV格式。 我想让这个类尽可能通用,以便它可以用于不同类型的数据。

我首先编写了以下方法:

public void Serialize<T>(IEnumerable<T> pList)
    {
        _content.AppendLine(string.Join(_seperator, pList.Select(x => ObjectToCsvString(x)).ToArray()));
    }

然后我意识到序列化诸如列表列表之类的对象会很好。所以我添加了这个方法:

public void Serialize<T>(IEnumerable<IEnumerable<T>> pList)
    {
        if (pList != null && pList.Any())
        {
            foreach (IEnumerable<T> list in pList)
            {
                Serialize(list);
            }
        }
    }

所以这没有用。如果我传入列表列表,它仍将直接进入第一种方法。我假设它可能与IEnumerable(IEnumerable(T))技术上也是IEnumerable(T)的事实有关。但我不太确定。之后我尝试了这种方法:

public void Serialize<T>(IEnumerable<T> pList)
    {
        if (pList != null && pList.Any())
        {
            if (pList is IEnumerable<IEnumerable<T>>) //example: list of lists of strings
            {
                foreach (IEnumerable<T> list in pList)
                {
                    Serialize(list);
                }
            }
            else //write CSV line
                _content.AppendLine(string.Join(_seperator, pList.Select(x => ObjectToCsvString(x)).ToArray()));
        }
    }

与此方法类似,当我传入字符串列表列表时,从未执行过if语句。我能够使用列表列表的唯一方法是使用此方法:

public void Serialize<T>(IEnumerable<T> pList)
    {
        if (pList != null && pList.Any())
        {
            if (pList is IEnumerable<IEnumerable<Object>>) //example: list of lists of strings
            {
                foreach (IEnumerable<Object> list in pList)
                {
                    Serialize(list);
                }
            }
            else //write CSV line
                _content.AppendLine(string.Join(_seperator, pList.Select(x => ObjectToCsvString(x)).ToArray()));
        }
    }

我遇到的问题是 1)为什么这两种方法不适用于列表列表? 2)我是否应该为此使用泛型?我觉得我对仿制药的理解并不合理。 3)有没有更好的方法来完成列表列表?

1 个答案:

答案 0 :(得分:0)

它根本不起作用,因为在

public void Serialize<T>(IEnumerable<T> pList)
{
    if (pList != null && pList.Any())
    {
        if (pList is IEnumerable<IEnumerable<T>>) //example: list of lists of strings
        {
            foreach (IEnumerable<T> list in pList)
            {
                Serialize(list);
            }
        }
        else //write CSV line
            _content.AppendLine(string.Join(_seperator, pList.Select(x => ObjectToCsvString(x)).ToArray()));
    }
}

你接受IEnumerable作为参数,IEnumerable永远不会是IEnumerable&gt; T不是一个神奇的词,它是传递的任何东西,所以如果你传入一个T列表,那么T是List,List是IEnumerable而不是IEnumerable&gt;

一个简单的处理方法是担心所有这一切在循环内部而不是在外面并立即处理所有事情是为了避免使用通用版本的T(因为你将它传递给一个似乎能够的方法把所有对象带到路上)并做这样的事情(更改为写入控制台的例子)。这甚至适用于包含一些列表元素和一些常规元素的任意列表和列表

void Main()
{
    List<object> mylist = new List<object> 
    {
        "test",
        DateTime.Now,
        new List<TimeSpan>()
        {
            TimeSpan.FromSeconds(10),
            TimeSpan.FromMinutes(10)
        }
    };

    Serialize(mylist);
}

public string ObjectToCSVString(object obj)
{
    return obj.ToString();
}

public void Serialize(IEnumerable Sequence)
{
    foreach (var item in Sequence)
    {
        if (item is IEnumerable && !(item is string)) // careful, string is IEnumerable<char>
        {
            Serialize(item as IEnumerable);
        }
        else
        {
            Console.WriteLine(ObjectToCSVString(item));
        }
    }
}