ParamsArray.cs 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. namespace System
  5. {
  6. internal readonly struct ParamsArray
  7. {
  8. // Sentinel fixed-length arrays eliminate the need for a "count" field keeping this
  9. // struct down to just 4 fields. These are only used for their "Length" property,
  10. // that is, their elements are never set or referenced.
  11. private static readonly object[] s_oneArgArray = new object[1];
  12. private static readonly object[] s_twoArgArray = new object[2];
  13. private static readonly object[] s_threeArgArray = new object[3];
  14. private readonly object _arg0;
  15. private readonly object _arg1;
  16. private readonly object _arg2;
  17. // After construction, the first three elements of this array will never be accessed
  18. // because the indexer will retrieve those values from arg0, arg1, and arg2.
  19. private readonly object[] _args;
  20. public ParamsArray(object arg0)
  21. {
  22. _arg0 = arg0;
  23. _arg1 = null;
  24. _arg2 = null;
  25. // Always assign this.args to make use of its "Length" property
  26. _args = s_oneArgArray;
  27. }
  28. public ParamsArray(object arg0, object arg1)
  29. {
  30. _arg0 = arg0;
  31. _arg1 = arg1;
  32. _arg2 = null;
  33. // Always assign this.args to make use of its "Length" property
  34. _args = s_twoArgArray;
  35. }
  36. public ParamsArray(object arg0, object arg1, object arg2)
  37. {
  38. _arg0 = arg0;
  39. _arg1 = arg1;
  40. _arg2 = arg2;
  41. // Always assign this.args to make use of its "Length" property
  42. _args = s_threeArgArray;
  43. }
  44. public ParamsArray(object[] args)
  45. {
  46. int len = args.Length;
  47. _arg0 = len > 0 ? args[0] : null;
  48. _arg1 = len > 1 ? args[1] : null;
  49. _arg2 = len > 2 ? args[2] : null;
  50. _args = args;
  51. }
  52. public int Length
  53. {
  54. get { return _args.Length; }
  55. }
  56. public object this[int index]
  57. {
  58. get { return index == 0 ? _arg0 : GetAtSlow(index); }
  59. }
  60. private object GetAtSlow(int index)
  61. {
  62. if (index == 1)
  63. return _arg1;
  64. if (index == 2)
  65. return _arg2;
  66. return _args[index];
  67. }
  68. }
  69. }