Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取方法参数的名称_C#_Optional Parameters_Nameof - Fatal编程技术网

C# 获取方法参数的名称

C# 获取方法参数的名称,c#,optional-parameters,nameof,C#,Optional Parameters,Nameof,我有一个有大量参数的方法。其中一些是可选的。因此,为了方便地使用此方法,我使用了可选参数特性 此外,该方法仅针对非空参数构建一个字典,其中参数名称作为字典的键,参数值作为字典的值 方法如下: public string CreateParameterDictionary( string id, string firstName, string lastName, string address, string postalCode, string l

我有一个有大量参数的方法。其中一些是可选的。因此,为了方便地使用此方法,我使用了可选参数特性

此外,该方法仅针对非空参数构建一个
字典
,其中参数名称作为字典的键,参数值作为字典的值

方法如下:

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;
}
如您所见,该方法有点冗长。我想知道是否有一种更简洁的方式来写它(无需思考)

谢谢大家!

编辑

谢谢你的回答,不过我的问题不太清楚。只是一个精度:

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

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

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

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

    }
公共字符串CreateParameterDictionary(
字符串参数1,
字符串参数2,
字符串参数3,
字符串参数4,
字符串参数5,
参数字符串[]可选参数(参数)
{

Contract.Requires(optionalParameters.Length将来,如果您有那么多参数:

// 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);
}
  • 使用数组,或
  • 将它们放在结构或类中
在这种情况下,可以使用数组:

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

请考虑使用PARAM关键字。请查看示例以了解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
    }

我建议使用
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);
}

那么,一个有那么多参数的方法肯定是一种代码味道。 我会考虑创建一个支持类,用作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);
    }
}
YourBusinessObjectRequestDto的公共类
{
公共字符串id{get;set;}
公共字符串名{get;set;}
公共字符串lastName{get;set;}
公共字符串地址{get;set;}
公共字符串postalCode{get;set;}
...
公共词典
{
var dict=新字典()
{
{“id”,id},
{“firstName”,firstName},
{“lastName”,lastName},
{“地址”,地址},
{“postalCode”,postalCode},
{ "...", ... }
};
返回dict.Where(pair=>pair.Value!=null).ToDictionary(pair=>pair.Key,pair=>pair.Value);
}
}
代码有点重复,但尽可能简单,并且符合我的口味

如果您可以将维护的方便性与性能进行权衡,那么就可以利用绝大多数Json库的动态序列化功能

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

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);
}    
ToDictionary()公共词典
{
var json=JsonConvert.SerializeObject(this);
var serializerSettings=new JsonSerializerSettings{NullValueHandling=NullValueHandling.Ignore};
返回JsonConvert.DeserializeObject(json,SerializeSettings);
}    
它不会尽可能快,但只要处理简单的类型,它就会执行得很好,并适应列表中的每个参数

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

编辑:
我错过了“排除非空值”要求。我编辑了代码以支持这一点。

但是现在您已经丢失了名称->值映射,因为不清楚数组中的第一个成员是作为
param6
还是作为
param16
传递的。参数的名称目前被用作字典中的键。@Damien\u不信者,您没有丢失它。使用params,您将通过其在数组中的位置访问值。因此,第6个param位于第一位,第7个进入第二位,等等。这与可选参数相同,因为您不能跳过前10个,而只为param16设置一个值,在这两种情况下,您都需要填充前面的所有参数。完全可以调用操作现有方法为
CreateParameterDictionary(“a”、“b”、“c”、“d”、“e”,参数16:“p”);
。您是否错过了关于@Damien_的备忘录?不信者,您是对的,我忘记了这一点:)您可能想将我给Radin的示例合并到我的一个注释中-
CreateParameterDictionary(“a”、“b”、“c”、“d”、“e”,参数16:“p”);
-很明显,可选参数不会“用完”或按声明顺序指定,这就是为什么
params
解决方案都是错误的,如果这是您的意图的话。(当然,在您的问题中,您可以进一步充实示例。我需要一些东西来添加注释)甚至
params字符串[]param
是的,我觉得提问者心里有这样一个答案。
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);
}