Arguments.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. namespace Masuit.Tools.Dynamics.Implementation;
  6. internal static class Arguments
  7. {
  8. public static INamedEnumerable<T> FromT<T>(IEnumerable<T> arguments, IEnumerable<string> names)
  9. {
  10. return new NamedEnumerable<T>(arguments, names);
  11. }
  12. public static INamedEnumerable<object> From(IEnumerable<object> arguments, IEnumerable<string> names)
  13. {
  14. return new NamedEnumerable<object>(arguments, names);
  15. }
  16. private class NamedEnumerable<T> : INamedEnumerable<T>
  17. {
  18. private readonly IEnumerable<T> _arguments;
  19. private readonly IEnumerable<string> _names;
  20. public NamedEnumerable(IEnumerable<T> arguments, IEnumerable<string> names)
  21. {
  22. if (arguments == null)
  23. {
  24. throw new ArgumentNullException(nameof(arguments));
  25. }
  26. if (names == null)
  27. {
  28. throw new ArgumentNullException(nameof(names));
  29. }
  30. var list = arguments.ToList();
  31. var nameList = names.ToList();
  32. if (list.Count < nameList.Count)
  33. {
  34. throw new ArgumentException("arguments.Count() < names.Count()");
  35. }
  36. _arguments = list;
  37. _names = nameList;
  38. }
  39. IEnumerator IEnumerable.GetEnumerator()
  40. {
  41. return _arguments.GetEnumerator();
  42. }
  43. IEnumerator<T> IEnumerable<T>.GetEnumerator()
  44. {
  45. return _arguments.GetEnumerator();
  46. }
  47. IEnumerable<T> INamedEnumerable<T>.Positional => _arguments.Take(_arguments.Count() - _names.Count());
  48. IDictionary<string, T> INamedEnumerable<T>.Named => new Named(_arguments, _names);
  49. private class Named : IDictionary<string, T>
  50. {
  51. private readonly IEnumerable<T> _arguments;
  52. private readonly IEnumerable<string> _names;
  53. private ICollection<T> _argumentsCollection;
  54. private ICollection<string> _namesCollection;
  55. public Named(IEnumerable<T> arguments, IEnumerable<string> names)
  56. {
  57. var args = arguments as IList<T> ?? arguments.ToList();
  58. var ns = names as IList<string> ?? names.ToList();
  59. _arguments = args.Skip(args.Count - ns.Count());
  60. _names = ns;
  61. }
  62. private IEnumerable<KeyValuePair<string, T>> MakeEnumerable()
  63. {
  64. return _arguments.Zip(_names, (arg, name) => new KeyValuePair<string, T>(name, arg));
  65. }
  66. IEnumerator<KeyValuePair<string, T>> IEnumerable<KeyValuePair<string, T>>.GetEnumerator()
  67. {
  68. return MakeEnumerable().GetEnumerator();
  69. }
  70. IEnumerator IEnumerable.GetEnumerator()
  71. {
  72. return MakeEnumerable().GetEnumerator();
  73. }
  74. void ICollection<KeyValuePair<string, T>>.Add(KeyValuePair<string, T> item)
  75. {
  76. throw new NotImplementedException();
  77. }
  78. void ICollection<KeyValuePair<string, T>>.Clear()
  79. {
  80. throw new NotImplementedException();
  81. }
  82. bool ICollection<KeyValuePair<string, T>>.Contains(KeyValuePair<string, T> item)
  83. {
  84. return MakeEnumerable().Contains(item);
  85. }
  86. void ICollection<KeyValuePair<string, T>>.CopyTo(KeyValuePair<string, T>[] array, int arrayIndex)
  87. {
  88. throw new NotImplementedException();
  89. }
  90. bool ICollection<KeyValuePair<string, T>>.Remove(KeyValuePair<string, T> item)
  91. {
  92. throw new NotImplementedException();
  93. }
  94. int ICollection<KeyValuePair<string, T>>.Count => _names.Count();
  95. bool ICollection<KeyValuePair<string, T>>.IsReadOnly => true;
  96. bool IDictionary<string, T>.ContainsKey(string key)
  97. {
  98. return _names.Contains(key);
  99. }
  100. void IDictionary<string, T>.Add(string key, T value)
  101. {
  102. throw new NotImplementedException();
  103. }
  104. bool IDictionary<string, T>.Remove(string key)
  105. {
  106. throw new NotImplementedException();
  107. }
  108. bool IDictionary<string, T>.TryGetValue(string key, out T value)
  109. {
  110. var pair = MakeEnumerable().FirstOrDefault(kv => kv.Key == key);
  111. value = pair.Value;
  112. return pair.Key != null;
  113. }
  114. T IDictionary<string, T>.this[string key]
  115. {
  116. get => MakeEnumerable().Where(kv => kv.Key == key).Select(kv => kv.Value).FirstOrDefault();
  117. set => throw new NotImplementedException();
  118. }
  119. ICollection<string> IDictionary<string, T>.Keys => _namesCollection ??= _names as ICollection<string> ?? _names.ToArray();
  120. ICollection<T> IDictionary<string, T>.Values => _argumentsCollection ??= _arguments as ICollection<T> ?? _arguments.ToArray();
  121. }
  122. }
  123. public static INamedEnumerable<object> Empty()
  124. {
  125. return From(Enumerable.Empty<object>(), Enumerable.Empty<string>());
  126. }
  127. }