LINQ to Objects - 将ICollection的属性通用转换为CSV

时间:2012-08-15 13:12:40

标签: c# linq linq-to-objects

我一直在我的代码中的几个不同的地方写这个,我想创建一个单一的泛型函数,但我无法弄清楚如何。

这是我正在做的一个例子:

public static string FormatCompaniesAsCSV(ICollection<Company> companies)
{
    string csv = "";
    foreach(Company c in companies)
    {
        csv += c.CompanyName + ",";
    }

    return csv.Substring(0, csv.LastIndexOf(","));
}

问题是,如果我想显示所有公司SKU或制造它的所有工厂,我必须编写基本相同的代码。唯一改变的是对象类型和我正在访问的属性。我想做的事情如下:

public static string FormatCSV<T>(ICollection<T> elements, string propertyName)
{
    string csv = "";
    foreach(T element in elements)
    {
        //I know this next line doesn't work
        //this is just a high level conceptualization of what I want to do
        csv += element.getPropertyValue(propertyName) + ","; 
    }

    return csv.Substring(0, csv.LastIndexOf(","));
}

我需要一些方法来访问foreach循环中元素的属性,但我真的不知道从哪里开始。我简要地看了一下System.Linq.Expressions库,但是我找不到我在那里寻找的东西。

我是否在正确的轨道上?如果没有,是否有更好的方法来完成我想做的事情?

2 个答案:

答案 0 :(得分:4)

我建议你传递代表:

public static string FormatAsCSV<T>(IEnumerable<T> elements,
                                    Func<T, string> converter) 
{ 
    string csv = ""; 
    foreach(T element in elements) 
    { 
        csv += converter(element) + ","; 
    } 

    return csv.Substring(0, csv.LastIndexOf(",")); 
} 

您可以这样调用此方法:

FormatAsCsv(companies, x => x.CompanyName);
FormatAsCsv(factories, x => x.ZipCode + " " + x.City);

您甚至可以通过在第一个参数的类型之前添加this来创建扩展方法:

public static string FormatAsCSV<T>(this IEnumerable<T> elements,
                                    Func<T, string> converter) 

现在你可以这样称呼它:

companies.FormatAsCsv(x => x.CompanyName);
factories.FormatAsCsv(x => x.ZipCode + " " + x.City);

顺便说一句:我将类型从ICollection<T>更改为IEnumerable<T>,因为您只使用IEnumerable<T>的功能。

您可以改进CSV字符串的生成:

public static string FormatAsCSV<T>(this IEnumerable<T> elements,
                                        Func<T, string> converter) 
{
    return elements.Select(x => converter(x)).Aggregate((x, y) => x + "," + y);
}

答案 1 :(得分:0)

逗号的连续可以在一行中完成:

List<string> list = new List<string>() { "Hi", "Old" };
string line = String.Join(",", list.ToArray());

您也可以编写扩展方法(如此)

public static string SuperJoin(string joinCharacter, IEnumerable<string> strings)
{
    return String.Join(",", strings.ToArray());
}

然后使用Linq从对象中选择要组合的字段。没有代表需要