Arguments.cs 5.8 KB

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