11

In researching how to convert a NameValueCollection to a querystring, I have come across different methods. I am curious if the shorter lambda syntax is as efficient as it could be.

How to convert NameValueCollection to a (Query) String using a iterating function.

public static String ConstructQueryString(NameValueCollection parameters)
{
    List<String> items = new List<String>();

    foreach (String name in parameters)
        items.Add(String.Concat(name, "=", System.Web.HttpUtility.UrlEncode(parameters[name])));

    return String.Join("&", items.ToArray());
}

Join a NameValueCollection into a querystring in C# uses a lambda expression, which looks nice but I'm not sure if it is efficient code.

private static string JoinNvcToQs(NameValueCollection qs)
{
    return string.Join("&", Array.ConvertAll(qs.AllKeys, key => string.Format("{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(qs[key]))));
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
Kevin Hakanson
  • 41,386
  • 23
  • 126
  • 155

3 Answers3

11

I would do it like this:

public static string ConstructQueryString(NameValueCollection parameters)
{
    var sb = new StringBuilder();

    foreach (String name in parameters)
        sb.Append(String.Concat(name, "=", System.Web.HttpUtility.UrlEncode(parameters[name]), "&"));

    if (sb.Length > 0)
        return sb.ToString(0, sb.Length - 1);

    return String.Empty;
} 

This way you create less objects (that have to be cleaned up by the garbage collector)

Corne
  • 646
  • 1
  • 6
  • 19
  • For those (like me) who stumbled upon this as a general method of generating url from NameValueCollection, this does not work correctly for parameters with multiple values. Hint: loop over `parameters.GetValues(key)`. – mcNux Jun 12 '14 at 15:30
2

First of all, the best thing you can do is test and see if the performance is acceptable for your application, we can tell you generalities about performance but in the end it comes down to your needs and only you know the answers to that.

As to the question at hand, any time you use a delegate (which is what a lambda creates) rather than executing the code directly you'll take a performance hit. In most cases the hit is acceptable but if this code needs the absolute best possible performance (say it's in an inner loop) then you need to go with your first method.

That said, if you're creating a querystring, presumably you're about to hit the database which will likely take considerably longer than either method of creating the querystring in the first place.

Jon Norton
  • 2,969
  • 21
  • 20
1

NameValueCollection's ToString method will build the query string for you. I haven't done any benchmarking, but I'd imagine the implementation would be more efficient than something using lambdas or foreach.

(The ToString solution doesn't seem to be well-documented; I only found it because this answer used it in a code sample.)

Community
  • 1
  • 1
ecraig12345
  • 2,328
  • 1
  • 19
  • 26