循环(可选)方法参数

时间:2014-03-03 15:37:25

标签: c#

我正在编写一个简单的库,它提供对具有多个可选参数的REST Web服务的访问。

Sample URL:
http://localhost/doSomething?a=a&b=b&c=c

所以我的出发点是一个带有可选参数的方法。像这样:

public byte[] DoSomething(string a = null, string b = null, string c = null)
{
    string query = "doSomething";
    //Get Parameters
    if (a != null)
    {
        //Handle first ?
        query = String.Format("{0}&{1}={2}", query, "a", a);
    }
    [...]
}

你可以想象,如果你有很多参数,这会导致一个很长的方法。减少代码大小的一种方法是将每个参数添加到集合中:

public byte[] DoSomething(string a = null, string b = null, string c = null)
{
    string query = "doSomething";
    var parameters = new Dictionary<string, string> {{"a", a}, {"b", b}, {"c", c}};
    foreach (var parameter in parameters)
    {
        if (!String.IsNullOrEmpty(parameterPair.Value))
        {
            //Handle first ?
            query = String.Format("{0}&{1}={2}", query, parameter.Key, parameter.Value);
        }
    }
    [...] 
}

这有点适合,但我很好奇是否有更好的方法来解决这样的问题,而无需创建长if语句或手动创建集合。

5 个答案:

答案 0 :(得分:1)

这是一个选项:

public byte[] DoSomething(Tuple<string,string>[] kvp)
{
 ...
}

答案 1 :(得分:1)

一种方法是使用匿名类型和反射,如下所示:

public byte[] DoSomething(string a = null, string b = null, string c = null)
{
    var p = new { a, b, c };
    var parts = from property in p.GetType().GetProperties()
                let value = property.GetValue(p) as string
                where !string.IsNullOrEmpty(value)
                select string.Format("{0}={1}", property.Name, value);

    var query = "?" + string.Join("&", parts);

    [...]
}

答案 2 :(得分:1)

以下是使用params的示例:

byte[] DoSomething(params KeyValuePair<string, string>[] parameters)
{
    var builder = new StringBuilder();
    for (int i = 0; i < parameters.Length; i++)
    {
        builder.AppendFormat("{0}={1}", parameters[i].Key, parameters[i].Value);
        if (i != parameters.Length - 1)
        {
            builder.Append("&");
        }
    }
    string urlParams = builder.ToString(); // contains "param1=value1&param2=value2"
    ...
}

以下是如何使用它:

DoSomething(new[] { 
                    new KeyValuePair<string, string>("param1", "value1"), 
                    new KeyValuePair<string, string>("param2", "value2"), 
                    });

答案 3 :(得分:1)

根据T McKeown,Nasreddine和John Gibb的答案,我想出了一个“ParameterModel”。有WebService方法,它们基本上具有相同的参数+一些额外的参数,所以我想方设法使用继承。

public class BaseABCModel
{
    public string A { get; set; }
    public string B { get; set; }
    public string C { get; set; }

    public BaseABCModel(string a = null, string b = null, string c = null)
    {
        A = a;
        B = b;
        C = c;
    }

    public Dictionary<string, string> GetParameters()
    {
        return GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
       .ToDictionary(propertyInfo => propertyInfo.Name, propertyInfo => 
       (String) propertyInfo.GetValue(this));
    }
}


//Methods:
public byte[] DoSomething(BaseABCModel model)
{
    string query = GetQuery("doSomething", model.GetParameters())
}


public string GetQuery(string methodName, Dictionary<string, string> parameters)
{
    string parameterString = parameters.Where(parameter => !String.IsNullOrEmpty(parameter.Value))
    .Aggregate(String.Empty, (current, parameter) => String.Format(
    String.IsNullOrEmpty(current) ? "{0}?{1}={2}" : "{0}&{1}={2}",
    current, parameter.Key, parameter.Value));

    return methodName + parameterString;
}

答案 4 :(得分:0)

这是我想出的。我正在搞乱不做a = null,b = null params的想法。

        public byte[] mainoutput(string text)
    {

        byte[] retval = null;

        char[] delimeterChars = { '?' };

        string[] newparsm = text.Split(delimeterChars);
        string query = "";
        int count = 0;

        foreach (string s in newparsm)
        {
            count += 1;

            if (s.Length > 2)
            {
                if (count == 1)
                {
                    query = query + "?" + s;
                }
                else
                {
                    query = query + "&" + s;
                }
            }

        }
        Console.WriteLine(query);

        return retval;

    }