Разделенная строка, созданная в цикле
Я ищу лучший способ создать строку, разделенную на другую в цикле. Я имею в виду, например, читатель SQL:
StringBuilder sb = new StringBuilder();
while(reader.Read())
{
sb.Append(reader[0]);
sb.Append("<br />");
}
string result = sb.ToString();
result = result.Remove(result.LastIndexOf("<br />")); // <-
или создание строки SQL-запроса;
StringBuilder sb = new StringBuilder();
foreach(string v in values)
{
sb.Append(v);
sb.Append(",");
}
string query = sb.ToString()
query = query.Remove(query.LastIndexOf(",")); // <-
query = String.Concat("INSERT INTO [foo] ([bar]) VALUES(", query, ")");
Это лучшее, что я нашел:
List<string> list = new List<string>;
while(reader.Read())
{
list.Add(reader[0]);
}
string result = String.Join("<br />", list.ToArray());
Изменить: Я знаю о StringBuilder
, я не использовал его здесь только для некоторой ясности. Моя общая идея не использует Remove
/LastIndexOf
!
Ответы
Ответ 1
Я не поклонник StringBuilder, если вы действительно не знаете, что вам нужно беспокоиться о производительности. Он производит уродливый код. Я бы написал это так...
private IEnumerable<string> ReadAllStrings(DataReader reader)
{
while(reader.Read())
yield return reader[0];
}
String.Join("<br />", ReadAllStrings(reader).ToArray());
Если бы я делал это много, я мог бы рассмотреть метод расширения:
public static class Extensions
{
public static string JoinWith(this IEnumerable<string> strings, string separator)
{
return String.Join(separator, strings.ToArray());
}
}
Тогда мой код будет выглядеть так:
ReadAllStrings(reader).JoinWith("<br />");
Ответ 2
Как насчет:
StringBuilder builder;
while (reader.Read())
{
if( builder == null )
{
builder = new StringBuilder(reader[0]);
}
else
{
builder.Append("<br />");
builder.Append(reader[0]);
}
}
string result = builder.ToString();
Ответ 3
Это всего лишь комбинация нескольких лучших идей:
public static class Extensions
{
public static string JoinStrings(this DataReader reader, int ColumnIndex, string delimiter)
{
var result = new StringBuidler();
var delim = String.Empty;
while (reader.Read())
{
result.Append(delim).Append(reader[ColumnIndex].ToString());
delim = delimiter;
}
return result.ToString();
}
}
Теперь все, что вам нужно сделать, это вызвать его так:
string result = reader.JoinStrings(0, "<br/>");
Ответ 4
Другое решение .Net 2.0 - измените порядок:
reader.Read();
StringBuilder sb = new StringBuilder(reader[0]);
while(reader.Read())
{
sb.Append("<br />");
sb.Append(reader[0]);
}
string result = sb.ToString();
Ответ 5
public class Separator
{
private string sep;
private bool first = true;
public Separator(string sep)
{
this.sep = sep;
}
public virtual string ToString()
{
string reply = first ? "" : sep;
first = false;
return reply;
}
}
var sep = new Separator("<br/>");
var builder = new StringBuilder();
while (reader.Read())
{
builder.Append (sep.ToString()) ;
builder.Append (reader[0]) ;
}