命名参数

  使用可选参数时,可能发现某个方法有几个可选参数,但你可能只想给第三个可选参数传送值。从上一节介绍的语法来看,如果不提供前两个可选参数的值,就无法给第三个可选参数传送值。

  C# 4引入了命令参数(named parameters),它允许指定要使用哪个参数。这不需要在方法定义中进行任何特殊处理,它是一个在调用方法时使用的技术。其语法如下:

  1. MyMethod(
  2. <param1Name> : <param1Value>,
  3. ...
  4. <paramNName> : <paramNValue>);

  参数的名称是在方法定义中使用的变量名。

  只要命名参数存在,就可以采用这种方式指定需要的任意多个参数,而且参数的顺序是任意的。命名参数也可以是可选的。

  可以仅给方法调用中的某些参数使用命名参数。当方法签名中有多个可选参数和一些必选参数时,这是非常有用的。可以首先指定必选参数,再指定命名的可选参数。例如:

  1. MyMethod(
  2. requiredParameter1Value,
  3. optionalParameter5 : optionalParameter5Value);

  但注意,如果混合使用命名参数和位置参数,就必须先包含所有的位置参数,其后是命名参数。但是,只要全部使用命名参数,参数的顺序也可以不同。例如:

  1. MyMethod(
  2. optionalParameter5 : optionalParameter5Value
  3. requiredParameter1 : requiredParameter1Value);

  此时,必须包含所有必选参数的值。

  下面的示例介绍了如何使用命名参数和可选参数。

  1. public static class WordProcessor
  2. {
  3. public static List<string> GetWords (
  4. string sentence,
  5. bool capitalizeWords = false,
  6. bool reverseOrder = false,
  7. bool reverseWords = false)
  8. {
  9. List<string> words = new List<string>(sentence.Split(' '));
  10. if(capitalizeWords)
  11. words = CapitalizeWords(words);
  12. if(reverseOrder)
  13. words = ReverseOrder(words);
  14. if(reverseWords)
  15. words = ReverseWords(words);
  16. return words;
  17. }
  18. private static List<string> CapitalizeWords(
  19. List<string> words)
  20. {
  21. List<string> capitalizedWords = new List<string>();
  22. foreach(string word in words)
  23. {
  24. if(word.Length == 0)
  25. continue;
  26. if(word.Length == 1)
  27. capitalizedWords.Add(
  28. word[0].ToString().ToUpper());
  29. else
  30. capitalizedWords.Add(
  31. word[0].ToString().ToUpper()
  32. + word.Substring(1));
  33. }
  34. }
  35. private static List<string> ReverseOrder(List<string words>)
  36. {
  37. List<string> reversedWords = new List<string>();
  38. for(int wordIndex = words.Count - 1;
  39. wordInde >= 0; wordIndex--)
  40. reversedWords.Add(words[wordIndex]);
  41. return reversedWords;
  42. }
  43. private static List<string> ReverseWords(List<string> words)
  44. {
  45. List<string> reversedWords = new List<string>();
  46. foreach(string word in words)
  47. reversedWords.Add(ReverseWord(word));
  48. return reversedWords;
  49. }
  50. private static string ReverseWord(string work)
  51. {
  52. StringBuilder sb = new StringBuilder();
  53. for(int characterIndex = word.Length - 1;
  54. characterIndex >= 0; characterIndex--)
  55. sb.Append(word[characterIndex]);
  56. return sb.ToString();
  57. }
  58. static void Main(string[] args)
  59. {
  60. string sentence = "'twas brillig, and the slithy toves did gyre "
  61. + "and gimble in the wabe:";
  62. List<string> words;
  63. words = WordProcessor.GetWords(sentence:);
  64. foreach(string word in words)
  65. {
  66. Console.Write(word);
  67. Console.Write(' ');
  68. }
  69. Console.WriteLine('\n');
  70. words = WordProcessor.GetWords(
  71. sentence,
  72. reverseWords : true,
  73. capitalizeWords : true);
  74. Console.WriteLine("Capitalized sentence with reversed words:");
  75. foreach(string word in words)
  76. {
  77. Console.Write(word);
  78. Console.Write(' ');
  79. }
  80. Console.ReadKey();
  81. }
  82. }
  示例的说明  这个示例创建了一个执行一些简单的字符串处理的实用类,再使用这个类修改一个字符串。类中的单个公共方法包含一个必选参数和3个可选参数:

  1. public static List<string> GetWords (
    string sentence,
    bool capitalizeWords = false,
    bool reverseOrder = false,
    bool reverseWords = false)
    {

    }


  这个方法返回string值的一个集合,每个string值都是初始输入的一个单词。根据指定的可选参数,可能会进行额外的转换: 对字符串集合进行整体转换,或者仅转换某个单词。  这里并未深入探讨WordProcessor类的功能,读者可以自己研究它的代码,考虑一下如何改进这些代码,例如\'twas应该为\'Twas吗?如何进行这个修改?  调用这个方法时,只使用了两个可选参数,第三个参数(reverseOrder)使用其默认值false:

  1. words = WordProcessor.GetWords(
    sentence,
    reverseWords : true,
    capitalizeWords true);


  还要注意,所指定的两个参数的顺序与定义它们的顺序不同。  最后要注意的是,处理带有可选参数的方法时,使用IntelliSense会非常方便。输入这个示例的代码时,注意GetWords()方法的工具提示,如图14-10所示(把鼠标指针停放在方法调用上,也会看到这个工具提示)。

 14.5.2 命名参数  - 图1

  这是一个非常有用的工具提示,它不仅显示了可用参数的名称,还显示了可选参数的默认值,非常便于确定是否需要重写某个默认值。