获取参数方法

时间:2016-06-20 08:38:46

标签: c# optional-parameters nameof

我有一个包含大量参数的方法。其中一些是可选的。因此,为了方便使用此方法,我使用可选参数功能。

此外,此方法构建一个Dictionary<string,string>,其参数名称为字典的键,参数值仅为非空参数的字典值。

以下是方法:

public string CreateParameterDictionary(
    string id,
    string firstName,
    string lastName,
    string address,
    string postalCode,
    string lorem = null,
    string ipsum = null,
    string dolor = null,
    //...
    string sit = null,
    string amet = null)
{
    if (String.IsNullOrWhiteSpace(id) ||
        String.IsNullOrWhiteSpace(firstName) ||
        String.IsNullOrWhiteSpace(lastName) ||
        String.IsNullOrWhiteSpace(address) ||
        String.IsNullOrWhiteSpace(postalCode))
    {
        throw new ArgumentNullException($"nameof((id) nameof(firstName) nameof(lastName) nameof(address) nameof(postalCode)");
    }

    Dictionary<string,string> parametersDictionary = new Dictionary<string, string>();
    parametersDictionary.Add(nameof(((id),((id);
    parametersDictionary.Add(nameof(firstName),firstName);
    parametersDictionary.Add(nameof(lastName),lastName);
    parametersDictionary.Add(nameof(address),address);
    parametersDictionary.Add(nameof(postalCode),postalCode);

    if (!String.IsNullOrWhiteSpace(lorem)) parametersDictionary.Add(nameof(lorem), lorem);
    if (!String.IsNullOrWhiteSpace(ipsum)) parametersDictionary.Add(nameof(ipsum), ipsum);
    if (!String.IsNullOrWhiteSpace(dolor)) parametersDictionary.Add(nameof(dolor), dolor);
    //...
    if (!String.IsNullOrWhiteSpace(sit)) parametersDictionary.Add(nameof(sit), sit);
    if (!String.IsNullOrWhiteSpace(amet)) parametersDictionary.Add(nameof(amet), amet);

    return parametersDictionary;
}

可以使用命名参数调用:

CreateParameterDictionary(5, "Dexter, "Morgan", "Miami", 12345, dolor: 5);

如您所见,该方法有点冗长。我想知道是否有更简洁的方法来编写它(没有反射)

谢谢!

修改

感谢您的回答然而,我不清楚我的问题。只是一个精度:

    我实际方法中的
  • 参数名称不是param1,param2等,而是更多的商业名称,如id,firstName,lastName,address1 = null。 像我们这样使用这种方法时,更容易知道哪个参数是强制性的。在此之前我使用了params string []但是当我使用它时,我不能使用参数的名称。

希望我的解释现在更清楚了。

5 个答案:

答案 0 :(得分:3)

嗯,一个包含许多参数的方法肯定会有代码味道。 我会考虑创建一个支持类,用作DTO(数据传输对象)。

简单的事情:

public class YourBusinessObjectRequestDto
{
    public string id { get; set; }
    public string firstName { get; set; }
    public string lastName { get; set; }
    public string address { get; set; }
    public string postalCode { get; set; }
    ...

    public Dictionary<string, string> ToDictionary()
    {
        var dict = new Dictionary<string, string>()
        {
          { "id", id },
          { "firstName", firstName },
          { "lastName", lastName },
          { "address", address },
          { "postalCode", postalCode },
          { "...", ... }
        };

        return dict.Where(pair => pair.Value != null).ToDictionary(pair => pair.Key, pair => pair.Value);
    }
}

代码略有重复,但尽可能简单,并且足以满足我的口味。

如果您可以通过性能交换易维护性,则可以利用绝大多数Json库的动态序列化功能。

使用Json.Net,您可以执行以下操作:

public Dictionary<string, string> ToDictionary()
{
    var json = JsonConvert.SerializeObject(this);

    var serializerSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };

    return JsonConvert.DeserializeObject<Dictionary<string, string>>(json, serializerSettings);
}    

它不会尽可能快,但只要您处理简单类型,它就会很好地执行并适应您可以投入列表的每个参数。

这种方法的优点是调试和管理非常简单:不需要位置参数。

编辑: 我错过了&#34;排除非空值&#34;需求。我编辑了代码以支持它。

答案 1 :(得分:0)

将方法重构为以下内容并使用代码协定来检查参数长度。这样,如果尝试使用少于5个参数的话,就会出现编译时错误。

 public string CreateParameterDictionary(
      string param1,
      string param2,
      string param3,
      string param4,
      string param5,
      params string[] optionalParametes)
    {
      Contract.Requires(optionalParametes.Length <= 24);

    }

答案 2 :(得分:0)

将来,如果您有这么多参数:

  • 使用数组或
  • 将它们放在结构或类中。

在这种情况下,您可以使用数组:

public string CreateParameterDictionary(string[] param)
{
    ... same as before, but using param[4] instead of param4, etc...
}

答案 3 :(得分:0)

请考虑使用param关键字。查看this示例以了解params关键字的用法。它将帮助您将可变数量的参数传递给方法。更改后,您的方法签名将如下所示:

public string CreateParameterDictionary(
        string param1,
        string param2,
        string param3,
        string param4,
        string param5,
        param string[] variableParams = null,
       )
    {
          //variableParams will contain your parameters from param6 to param30
    }

答案 4 :(得分:0)

我建议使用params代替参数列表:

// you want to return Dictionary<String, String>  - right?
// static - I can't see any use of "this" in the method
public static Dictionary<string, string> CreateParameterDictionary(
  params String[] values) {

  if (null == values)
    throw new ArgumentNullException("values");

  // Required: we want at least 5 parameters
  if (values.Length < 5)
    throw new ArgumentException("Too few parameters");

  // First 5 parameters must not be null or empty
  if (values.Take(5).Any(item => String.IsNullOrEmpty(item)))
    throw new ArgumentException("First five parameters must not be null or empty");

  return values
    .Select((item, index) => new {
      index = index + 1,
      value = item
    })
    .Where(item => !String.IsNullOrWhiteSpace(item.value))
    .ToDictionary(item => "param" + item.index.ToString(),
                  item => item.value);
}

测试:

  var result = CreateParameterDictionary("A", "B", "C", "D", "E", "F");

  String report = String.Join(Environment.NewLine, 
    result.Select(pair => String.Format("{0} = {1}", pair.Key, pair.Value)));

  // param1 = A
  // param2 = B
  // param3 = C
  // param4 = D
  // param5 = E
  // param6 = F
  Console.Write(report);