我一直在我的代码中的几个不同的地方写这个,我想创建一个单一的泛型函数,但我无法弄清楚如何。
这是我正在做的一个例子:
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库,但是我找不到我在那里寻找的东西。
我是否在正确的轨道上?如果没有,是否有更好的方法来完成我想做的事情?
答案 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从对象中选择要组合的字段。没有代表需要