如何从一个泛型列表<T>创建一个CSV字符串

3
我有以下代码,用于返回一个泛型列表,我想要遍历该列表,并生成一个逗号分隔的值的字符串。
public static List<ReportCriteriaItem> GetCurrentSelection(ReportWizardCriteriaType criteriaType)
    {
        return Criteria.CriteriaList.FindAll(delegate(ReportCriteriaItem item) 
                                                { return item.CriteriaType == criteriaType; }
                                            );
    }

这里是ReportCriteriaItem的定义 - 我将其制作成通用列表的对象...我认为这是关键,要将其"id"字段导入CSV:

public class ReportCriteriaItem
{
    [System.Xml.Serialization.XmlAttribute("id")]
    public string Id { get; set; }

    [System.Xml.Serialization.XmlAttribute("name")]
    public string Name { get; set; }

    [System.Xml.Serialization.XmlAttribute("value")]
    public string Value { get; set; }

    [System.Xml.Serialization.XmlAttribute("type")]
    public ReportWizardCriteriaType CriteriaType { get; set; }

    public ReportCriteriaItem() { }
    public ReportCriteriaItem(ReportWizardCriteriaType criteriaType, string id, string name, string value)
    {
        this.Id = id;
        this.Name = name;
        this.Value = value;
        this.CriteriaType = criteriaType;
    }
}

我能使用for each循环来做这件事吗?

希望大家不介意标题的更改...更能准确地反映实际问题。 - Josh
哈哈...需要一个“墨西哥僵局”标签 ;) - Josh
6个回答

4

最简单的方法是使用 string.Join

string joined = string.Join(",", GetCurrentSelection(...).Select(x => x.Value));

你要做的确切细节取决于你使用的C#和.NET版本,但以上只是一个例子。如果你能给我们更多细节,我们就可以给你更具体的代码。

(特别地,在.NET 3.5中,你需要向string.Join提供一个数组;在.NET 4中则不需要。你使用的.NET版本比你使用ASP.NET的事实更重要。)


我正在使用.NET 4.0,但它不喜欢我尝试加入一个泛型列表,有什么想法吗? - kacalapy
使用以下代码:var csv = String.Join(",", GetCurrentSelection(criteriaType).ToArray() ); 我被告知参数无效...? - kacalapy
@kalapy:如果您真正在使用. Net 4,那么即使没有调用ToArray,也应该没问题——但请注意它将对每个值调用ToStrung。这是您想要的吗?如果不是,请按照我的答案使用投影。 - Jon Skeet

3
如果您已经有了列表,那么您可以直接使用String.Join方法:
var myList = GetCurrentSelection(ReportWizardCriteriaType.SomeCriteria);
var csv = String.Join(",",myList.ToArray());

Voila!


糟糕!我意识到我的参数颠倒了...现在已经修复了。 - Josh

2

如果您拥有 .net 4,您可以使用 String.Join<T>(string, IEnumerable<T>) 方法:

string csv = string.Join(", ", GetCurrentSelection(...));

字符串项是通过在ReportCriteriaItem上执行ToString()来生成的。如果字符串值必须通过访问您的ReportCriteriaItem的某个其他方法或属性来生成(或者如果您使用的是小于4的.NET版本),则Jon Skeet的答案是正确的方法。


我有一个问题:var csv = String.Join(",", GetCurrentSelection(criteriaType)); 不喜欢我尝试加入一个GENERIC列表而不是一个数组。 - kacalapy
@kacalapy:这很奇怪,它应该在4.0版本中可以工作。不幸的是,我现在没有可用的Visual Studio进行测试... - Heinzi

1
string list = "";
foreach (ReportCriteriaItem item in GetCurrentSelection(...)) {
    if (!string.IsNullOrEmpty(list)) list += ",";
    list += item.???;
}
// do something with the list.

请注意,如果字段包含“,”,那么这将无法正常工作。 - Oscar Mederos

1

我喜欢使用一行代码的解决方案,但由于对象的本质以及该对象是我的目标,我必须循环并提取每个通用项的值...

string csv = "";
            foreach (ReportCriteriaItem item in GetCurrentSelection(criteriaType))
            {
                csv += item.Id + ",";
            }
            return csv.TrimEnd(",".ToArray() ) ;

1
删除最后一个逗号的简单方法。在循环中使用if语句总是让我感到烦恼。 - argatxa

0

享受吧!

public static class DataHelper
{
   public static string ToCsv<T>(string separator, IEnumerable<T> objectlist)
   {
                Type t = typeof(T);
                PropertyInfo[] fields = t.GetProperties();

                string header = String.Join(separator, fields.Select(f => f.Name).ToArray());

                StringBuilder csvdata = new StringBuilder();
                csvdata.AppendLine(header);

                foreach (var o in objectlist)
                    csvdata.AppendLine(ToCsvFields(separator, fields, o));

                return csvdata.ToString();
            }

public static string ToCsvFields(string separator, PropertyInfo[] fields, object o)
            {
                StringBuilder linie = new StringBuilder();

                foreach (var f in fields)
                {
                    if (linie.Length > 0)
                        linie.Append(separator);

                    var x = f.GetValue(o);

                    if (x != null)
                        linie.Append(x.ToString());
                }

                return linie.ToString();
            }
    }

使用方法如下

var customers = new List<Customer>(); // Any simple class
string csv = DataHelper.ToCsv(";",customers ); 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接