在我们的代码中的许多地方,我们都有对象集合,我们需要从中创建以逗号分隔的列表.集合的类型各不相同:它可能是我们需要某个列的DataTable,或者是List
现在我们遍历集合并使用字符串连接,例如:
string text = ""; string separator = ""; foreach (DataRow row in table.Rows) { text += separator + row["title"]; separator = ", "; }
这有更好的模式吗?理想情况下,我希望通过发送函数来从每个对象获取正确的字段/属性/列,我们可以重用一种方法.
string.Join(", ", Array.ConvertAll(somelist.ToArray(), i => i.ToString()))
static string ToCsv(IEnumerable things, Func toStringMethod) { StringBuilder sb = new StringBuilder(); foreach (T thing in things) sb.Append(toStringMethod(thing)).Append(','); return sb.ToString(0, sb.Length - 1); //remove trailing , }
使用这样:
DataTable dt = ...; //datatable with some data Console.WriteLine(ToCsv(dt.Rows, row => row["ColName"]));
要么:
Listcustomers = ...; //assume Customer has a Name property Console.WriteLine(ToCsv(customers, c => c.Name));
我没有编译器,但理论上它应该工作.众所周知,理论上,实践和理论都是一样的.在实践中,他们不是.
// using System.Collections; // using System.Collections.Generic; // using System.Linq public delegate string Indexer(T obj); public static string concatenate (IEnumerable collection, Indexer 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 (IEnumerable collection, Indexer 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 listOfInts) { return concatenate (listOfInts, Convert.ToString, ','); } // example 2: DataTable.Rows string getTitle(DataRow row) { return row["title"].ToString(); } string getAllTitles(DataTable table) { return concatenate (table.Rows, getTitle, '\n'); } // example 3: DataTable.Rows without Indexer function string getAllTitles(DataTable table) { return concatenate (table.Rows, r => r["title"].ToString(), '\n'); }
我发现string.Join和Lambda Select>有助于编写最小代码.
Listfruits = new List (); fruits.Add("Mango"); fruits.Add("Banana"); fruits.Add("Papaya"); string commaSepFruits = string.Join(",", fruits.Select(f => "'" + f + "'")); Console.WriteLine(commaSepFruits); List ids = new List (); ids.Add(1001); ids.Add(1002); ids.Add(1003); string commaSepIds = string.Join(",", ids); Console.WriteLine(commaSepIds); List customers = new List (); customers.Add(new Customer { Id = 10001, Name = "John" }); customers.Add(new Customer { Id = 10002, Name = "Robert" }); customers.Add(new Customer { Id = 10002, Name = "Ryan" }); string commaSepCustIds = string.Join(", ", customers.Select(cust => cust.Id)); string commaSepCustNames = string.Join(", ", customers.Select(cust => "'" + cust.Name + "'")); Console.WriteLine(commaSepCustIds); Console.WriteLine(commaSepCustNames); Console.ReadLine();
您可以编写一个将IEnumerable转换为逗号分隔字符串的函数
public string Concat(IEnumerablestringList) { StringBuilder textBuilder = new StringBuilder(); string separator = String.Empty; foreach(string item in stringList) { textBuilder.Append(separator); textBuilder.Append(item); separator = ", "; } return textBuilder.ToString(); }
然后,您可以使用Linq查询集合/数据集/ etc以提供stringList.
在.NET 4中,您可以这样做 string.Join(", ", table.Rows.Select(r => r["title"]))