2010-01-06 3 views
10
chaîne

pour construire à l'aide KeyValuePair est comme ceci: "nom1 = v1 & nom2 = v2 & NAME3 = v3"une façon élégante de construire la chaîne en C#

ce que je fais:

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

un moyen élégant d'éviter la dernière déclaration de suppression du signe '&'?

+0

Je pense que c'est la meilleure façon vous le faites, il évite des contrôles supplémentaires pour chaque itération ci-dessous. – Ravia

Répondre

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

Étant donné que nous ne sommes pas concaténer à une grande chaîne (nous produisons beaucoup de petites cordes) La concaténation ne comporte aucune pénalité de performance dans ce cas. Et dans les chaînes .NET, la longueur est préfixée de toute façon, donc le problème de performance de concaténation est moins important qu'en C. String.Join() est aussi très rapide, plus rapide que StringBuilder.

TLDR: Utilisez String.Join()

+0

Vous avez oublié le "n =>" dans le Sélectionner. Var = String.Join ("&", nameValues.Select (n => String.Concat (n.Key, "=", n.Value)). ToArray()); – helium

+0

helium: Oui, je sais que je l'ai réparé. Je ne suis pas encore réveillé à 100%. –

+1

cool. rejoindre est incroyable – Benny

1

Eh bien au moins vous pouvez supprimer le signe & avant l'appel ToString() en faisant --sb.Length;

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

il suffit d'ajouter « & » en cas de besoin, ne retirez pas de fin.

+3

Et si la vitesse est un problème, utilisez sb.Append (name.Key) .Append ("="). Append (name.Value); – Will

5

Jetez un coup d'oeil ici: How to build a query string for a URL in C#?; Citant:

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

cuil! Cela aura l'air plus cool si on y accède en tant que méthode d'extension. –

+0

existe-t-il un NameValueCollection qui peut contenir une chaîne, une paire d'objets? – Benny

+0

Vous ne pouvez pas utiliser 'Dictionary '? –

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

Petite faute de frappe sur le premier AppendFormat - il n'a pas besoin du '&'. Cette méthode fonctionne très bien s'il y a au moins une entrée. – Will

3

Voici une autre approche que je l'ai parfois utilisé:

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

Il est juste une façon de préfixer & avant chaque paire autre que le premier, sans l'aide d'un test conditionnel.

Si vous voulez utiliser votre idée originale de tailler la StringBuilder en passant, je vous suggère plutôt le code suivant:

sb.Length--; // Remove the last character 
return sb.ToString(); 
+1

cool, sb.Length-- est plus efficace. – Benny

+2

Vous pouvez aussi aller avec '" & {0} = {1} "' et dépouiller le caractère _first_ avec un 'sb.ToString (1, sb.Length - 1)' –

3

J'ai tendance à utiliser, en utilisant le fait que vous pouvez tronquer un constructeur de chaîne avec un décrément sur la propriété de longueur:

var sb = new StringBuilder(); 

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

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