在许多地方,在我们的code,我们有对象,从中我们需要创建一个逗号分隔的列表的集合。集合的类型有所不同:它可能是一个数据表,从中我们需要某列,或List<客户>中等等
现在我们通过收集和使用字符串连接环,例如:
字符串文本=;
字符串分隔符=;
的foreach(DataRow的行table.Rows)
{
文字+ =分隔符+行[标题];
隔板=,;
}
对此有一个更好的模式?理想情况下,我想我们可以通过只发送一个函数来得到正确的字段/属性/每个对象列重用的方法。
解决方案 // System.Collections中使用;
//使用System.Collections.Generic;
//使用System.Linq的
公共委托字符串索引< T>(T OBJ);
公共静态字符串串连< T>(IEnumerable的< T>收集,索引器< T>索引,字符分隔符)
{
StringBuilder的SB =新的StringBuilder();
的foreach(在集合T(T))sb.Append(索引(t))的追加(分隔符)。
返回sb.Remove(sb.Length - 1,1)的ToString();
}
//版本非泛型集合
公共静态字符串串连< T>(IEnumerable集合,索引器< T>索引,字符分隔符)
{
StringBuilder的SB =新的StringBuilder();
。的foreach(在集合对象T)sb.Append(索引((T)t))的追加(分隔符);
返回sb.Remove(sb.Length - 1,1)的ToString();
}
//例子1:简单的INT表
字符串getAllInts(IEnumerable的< INT> listOfInts)
{
返回接续模式&其中; int的>(listOfInts,Convert.ToString,,);
}
//例子2:DataTable.Rows
字符串的getTitle(DataRow的行){返回行[标题]的ToString()。 }
字符串getAllTitles(DataTable的表)
{
返回串连< DataRow的>(table.Rows,的getTitle,' N');
}
//例子3:DataTable.Rows无索引功能
字符串getAllTitles(DataTable的表)
{
返回串连< DataRow的>(table.Rows,R =>的。R [标题]的ToString(),' N');
}
In many places in our code we have collections of objects, from which we need to create a comma-separated list. The type of collection varies: it may be a DataTable from which we need a certain column, or a List<Customer>, etc.
Now we loop through the collection and use string concatenation, for example:
string text = "";
string separator = "";
foreach (DataRow row in table.Rows)
{
text += separator + row["title"];
separator = ", ";
}
Is there a better pattern for this? Ideally I would like an approach we could reuse by just sending in a function to get the right field/property/column from each object.
解决方案// using System.Collections;
// using System.Collections.Generic;
// using System.Linq
public delegate string Indexer<T>(T obj);
public static string concatenate<T>(IEnumerable<T> collection, Indexer<T> indexer, char separator)
{
StringBuilder sb = new StringBuilder();
foreach (T t in collection) sb.Append(indexer(t)).Append(separator);
return sb.Remove(sb.Length - 1, 1).ToString();
}
// version for non-generic collections
public static string concatenate<T>(IEnumerable collection, Indexer<T> indexer, char separator)
{
StringBuilder sb = new StringBuilder();
foreach (object t in collection) sb.Append(indexer((T)t)).Append(separator);
return sb.Remove(sb.Length - 1, 1).ToString();
}
// example 1: simple int list
string getAllInts(IEnumerable<int> listOfInts)
{
return concatenate<int>(listOfInts, Convert.ToString, ',');
}
// example 2: DataTable.Rows
string getTitle(DataRow row) { return row["title"].ToString(); }
string getAllTitles(DataTable table)
{
return concatenate<DataRow>(table.Rows, getTitle, 'n');
}
// example 3: DataTable.Rows without Indexer function
string getAllTitles(DataTable table)
{
return concatenate<DataRow>(table.Rows, r => r["title"].ToString(), 'n');
}