在C#中构建字符串的优雅方法

10

"name1=v1&name2=v2&name3=v3" 这个字符串是使用 keyvaluepair 构建的。

我正在做的事情:

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);

有没有一种优雅的方法来避免删除“&”符号的最后一个语句?


我认为这是你正在做的最好方式,它避免了下面每次迭代的额外检查。 - Ravi Vanapalli
7个回答

18
var joined =
    String.Join("&", nameValues.Select(n => n.Key + "=" + n.Value).ToArray());

假设我们不是将多个字符串连接成一个大字符串(而是产生许多小字符串),在这种情况下,连接操作并不会带来性能上的惩罚。而且在.NET中,字符串已经有长度前缀,所以整个连接性能问题比在C中 less 相关。String.Join() 也非常快,比StringBuilder更快。

简而言之:使用 String.Join()


你在Select中忘记了"n =>"。var joined = String.Join("&", nameValues.Select(n => String.Concat(n.Key, "=", n.Value)).ToArray()); - helium
氦气:是的,我知道我已经修复了它。我还没有完全清醒。 - Tamas Czinege

5

请看这里:如何在C#中构建URL的查询字符串?;引用:

private string ToQueryString(NameValueCollection nvc)
{
    return "?" + 
        string.Join("&", 
            Array.ConvertAll(
                nvc.AllKeys, 
                key => String.Format("{0}={1}", HttpUtility.UrlEncode(key),
                HttpUtility.UrlEncode(nvc[key]))));
}

嘿!如果作为扩展方法访问,这会看起来更酷。 - this. __curious_geek
有没有一个可以容纳字符串、对象对的 NameValueCollection? - Benny
你不能使用 Dictionary<string, object> 吗? - Rubens Farias

4
foreach (var name in nameValues)
    {
        if (sb.Length > 0) sb.Append("&");
                sb.AppendFormat("{0}={1}", name.Key, name.Value);
     }

只需要在需要的时候添加"&",不要从结尾处删除它。

3
如果速度是关键,可以使用sb.Append(name.Key).Append("=").Append(name.Value); - Will

3

以下是我有时使用的另一种方法:

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();

2
你也可以选择使用"&{0}={1}",并用sb.ToString(1, sb.Length - 1)去掉第一个字符。 - Rubens Farias

3
我倾向于使用这种方法,利用了可以通过将长度属性递减来截断字符串生成器的事实:
var sb = new StringBuilder();

foreach (var name in nameValues)
{
    sb.AppendFormat("{0}={1}&", name.Key, name.Value);
} 

if (sb.Length > 0) sb.Length--;

1

至少你可以通过执行--sb.Length;来在调用ToString()之前删除&符号。


0
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);
} 

第一个AppendFormat上有个小错别字 - 它不需要'&'。如果至少有一个条目保证存在,这种方法非常有效。 - Will

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接