views:

132

answers:

9

I have a method that accepts a bunch of strings in seperate parameters

public string GetQueryString(string string1, string string2, string string3...)

It should return a string in the form of

"string1:value1 string2:value2 string3:value3..."

Because I don't want to put reflection logic in the callers of GetQueryString, I think working with string[,] parameters is not an option.

What I need now is a way to walk through all my parameters and add "parName:parValue" to my StringBuilder.
Currently I do this by checking each of them with an if clause

if (!string.IsNullOrEmpty(string1))
    sb.AppendFormat("{0}:{1}", "string1", string1);

How can this be improved?

--CLARIFICATION--
What I believe the OP wants to do is something like this:

string str1 = "Hello";
string s2 = "World";
string MyStr = "Greetings";
string YourStr = "Earthlings";
string query = GetQueryString(str1, s2, MyStr, YourStr);

and have it return "str1:Hello s2:World MyStr:Greetings YourStr:Earthlings"

--EDIT--
clarification is correct.
Furthermore, because my method is called GetQueryString doesn't mean I'm working on an HTML query string.. In this particular case it is actually a Lucene query string. But it could be any search function that can parse strings to a query..

A: 

I would use JSON for that, it is simple and plenty of frameworks out there.

Otávio Décio
Could you elaborate a bit?
borisCallens
+1  A: 

Why does params require reflection? One way to solve this in my opinion is to use a params keyword and use a dictionary for the name and value.

Or do it how your doing. If your using params you can provide some overloads that take one two or three parameters to avoid the array being built up. This is a tiny optimization string.format() does.

Edit

Another option is to create an object which represents the possible parameters and then serialize that. You could then use reflection to walk through your own fields, in which case you could create a base class and isolate the algorithim allowing different representations.

public abstract class QueryParams
{
  pubic string GetQueryString()
  {
    //use reflection here 
  }
}

public class MyQueryParams : QueryParams
{
   public QueryParam MyParam1
   {
    get
     {
          if (_myParam1==null)
          { 
             _myParam1=new QueryParam("MyParam1");
           }
           return _myParam1;
      }

}

public class QueryParam 
{
   public string Name;
   public string Value;
}

Edit

Modified above code sample to include QueryParam which lets your class own the name of the query parameters.

JoshBerke
Because I would need keyValuePairs (I need the name of the parameter), the calling method should then know what the name is.
borisCallens
A: 

Even if you don't like it very much this looks like a typical useage scenario for an array. If you absolutley must keep the GetQueryString with explicit string members, you could forward to another method, such as:

public string GetQueryString(string string1, string string2, string string3...)
{
    return GetQueryStringImpl(string1, string2, string3, ...);
}

public string GetQueryStringImpl(params string[] strings)
{
     foreach (string s in strings)
     {
          // check s for null and append to query string
     }
}

However I'd question the reason why you need those explicit parameters in the first place before using such a solution.

Update:

I just re-read and noticed that you wanted the names as well. As long as the values are strings something like this might work:

public string GetQueryString(string string1, string string2, string string3...)
{
    return GetQueryStringImpl("name1", string1, "name2", string2, "name3", string3, ...);
}

public string GetQueryStringImpl(params string[] strings)
{
     for (int i=0; i<strings.Length; i+=2)
     {
          var name = strings[i];
          var s = strings[i+1];
          // check s for null and append to query string
     }
}
froh42
A: 

This should give you what you want, with no reflection used:

public string GetQueryString(params string[] inStrings)
{
    StringBuilder sb = new StringBuilder();
    int iCount = 1;
    foreach (String s in inStrings)
    {
        if (iCount > 1)
            sb.Append(" ");        
        sb.AppendFormat("{0}{1}:{1}", "string", iCount, s);
        iCount++;
    }
    return sb.ToString();
}
Jess
indeed, because my example strings are called string1, string2 etc. But in real case scenarios these will be called things like "company" and "color"
borisCallens
A: 

Check out the QueryStringHelper class in this blog post:

http://bloggingabout.net/blogs/stephan/archive/2008/12/01/passing-query-string-parameters-to-a-silverlight-app-hosted-in-html.aspx

It uses regex to parse out the string-value pairs in a query string and puts them into an IDictionary<string, string>. You could then loop through it and add the key-value pairs into your StringBuilder if the value isn't null.

Cory Larson
A: 

This article might be helpful:

Andrew Hare
A: 
public string GetQueryString(params string[] paramName)
{
    var result = from p in paramName
                 where !String.IsNullOrEmpty(p)
                 select p + ":" + Request.QueryString[p];
    return String.Join(" ", result.ToArray());
}

Where the call might be:

Response.Write(GetQueryString("param1", "param2", "param4"));
John Saunders
this is explicitly web related whereas this is not the applicable in my case. I'm talking about Lucene query string if you would want to know.
borisCallens
+2  A: 

The problem is, as soon as you compile this, the variable names will go away. Reflection won't even help you.

The only thing I can think of that may work, is to use a expression tree (.NET v3.5+)

 string GetQueryString(Expression<Func<String, string>> exprTree )
 { 
     // walk expreTree.  
     // exprTree.Body.Left.Name would be the name of the variable
     // exprTree.Body.Left.Value would be it value.
 }

 string q = GetQueryString((str1, s2, MyS, YourS) => str1 + s2 + MyS + YourS);
James Curran
It's not really an easy solution, but your first statement is basically the "answer" I was looking for.
borisCallens
"the variable names will go away" Are u sure about this? Becasue relectors shows the correct variable names, therefore I assume .NET preserve them and they are somehow accessible.
dr. evil
Reflector does not always have the variable names for local variables. You see things like "flag2". Maybe it is able to see debug symbols.
John Saunders
@Slough, you're right, the parameter names does not go away as they are part of the method signature. They are readily available via Reflection.
Peter Lillevold
@Peter - The Receiving variable names are part of the signature. But here we need the Passed variable names, which are not preserved.
James Curran
Ah, sorry 'bout that. Didn't see the clarification.
Peter Lillevold
A: 

If the OP is looking to find the names of the actual parameters passed to his method, then it's very simple: it cannot be done. The names of actual parameters are not kept anywhere.

What would you want to display if the parameter were an expression?


Ok, that word "expression" triggered a recollection. You might be able to do something by using expression trees from LINQ. See Charlie Calvert's Community Blog : Expression Tree Basics and Expression Trees.

John Saunders