элегантный способ создания строки в С#
-
19-09-2019 - |
Вопрос
Строка для создания с использованием пары ключ-значение выглядит следующим образом:"имя1=v1&имя2=v2&имя3=v3"
что я делаю:
var sb = new StringBuilder();
foreach (var name in nameValues)
{
sb.AppendFormat("{0}={1}&", name.Key, name.Value);
}
//remove last '&' sign, this is what i think is ugly
sb.ToString().Remove(lastIndex);
есть ли элегантный способ избежать последнего оператора удаления знака «&»?
Решение
var joined =
String.Join("&", nameValues.Select(n => n.Key + "=" + n.Value).ToArray());
Учитывая, что мы не объединяем одну большую строку (мы создаем много маленьких строк), в этом случае объединение не приводит к снижению производительности.А в .NET строки в любом случае имеют префикс длины, поэтому вся проблема производительности конкатенации менее актуальна, чем в C.String.Join() также очень быстр, быстрее, чем StringBuilder.
TLDR: Использовать String.Join()
Другие советы
Посмотрите здесь: Как создать строку запроса для URL-адреса на C#?;Цитирую:
private string ToQueryString(NameValueCollection nvc)
{
return "?" +
string.Join("&",
Array.ConvertAll(
nvc.AllKeys,
key => String.Format("{0}={1}", HttpUtility.UrlEncode(key),
HttpUtility.UrlEncode(nvc[key]))));
}
foreach (var name in nameValues)
{
if (sb.Length > 0) sb.Append("&");
sb.AppendFormat("{0}={1}", name.Key, name.Value);
}
Просто добавьте «&», когда необходимо, не удаляйте его с конца.
Вот еще один подход, который я иногда использовал:
var sb = new StringBuilder();
string prefix = "";
foreach (var name in nameValues)
{
sb.Append(prefix);
prefix = "&";
sb.AppendFormat("{0}={1}", name.Key, name.Value);
}
Это просто способ добавления & перед каждой парой, кроме первой, без использования условной проверки.
Если вы хотите использовать свою оригинальную идею обрезки StringBuilder
кстати, я бы предложил вместо этого следующий код:
sb.Length--; // Remove the last character
return sb.ToString();
Я склонен использовать это, используя тот факт, что вы можете усечь построитель строк, уменьшив свойство длины:
var sb = new StringBuilder();
foreach (var name in nameValues)
{
sb.AppendFormat("{0}={1}&", name.Key, name.Value);
}
if (sb.Length > 0) sb.Length--;
Ну по крайней мере можно удалить &
подпишитесь перед ToString()
позвонить, сделав --sb.Length;
var sb = new StringBuilder();
sb.AppendFormat("{0}={1}", nameValues[0].Key, nameValues[0].Value);
for (int i = 1; i < nameValues.Count; i++)
{
sb.AppendFormat("&{0}={1}", nameValues[i].Key, nameValues[i].Value);
}