如何遍历IEnumerable>将数据序列化为CSV时

本文关键字:IEnumerable 序列化 数据 CSV 何遍历 遍历 | 更新日期: 2023-09-27 18:14:07

我正在编写一个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)是否有更好的方法来完成这个列表的列表?

如何遍历IEnumerable<IEnumerable<T>>将数据序列化为CSV时

它根本不起作用,因为在

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> T不是一个神奇的词,它是传递的任何东西,所以如果你传递一个list of list of T那么T就是list list list是IEnumerable而不是IEnumerable>

处理这个问题的一个简单方法是在循环内部而不是在外部处理所有的事情,避免使用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));
        }
    }
}