mscorlib(4.0.0.0) API with additions
ListDictionary.cs
1 using System.Threading;
2 
4 {
8  {
9  private class NodeEnumerator : IDictionaryEnumerator, IEnumerator
10  {
11  private ListDictionary list;
12 
13  private DictionaryNode current;
14 
15  private int version;
16 
17  private bool start;
18 
19  public object Current => Entry;
20 
21  public DictionaryEntry Entry
22  {
23  get
24  {
25  if (current == null)
26  {
27  throw new InvalidOperationException(SR.GetString("InvalidOperation_EnumOpCantHappen"));
28  }
29  return new DictionaryEntry(current.key, current.value);
30  }
31  }
32 
33  public object Key
34  {
35  get
36  {
37  if (current == null)
38  {
39  throw new InvalidOperationException(SR.GetString("InvalidOperation_EnumOpCantHappen"));
40  }
41  return current.key;
42  }
43  }
44 
45  public object Value
46  {
47  get
48  {
49  if (current == null)
50  {
51  throw new InvalidOperationException(SR.GetString("InvalidOperation_EnumOpCantHappen"));
52  }
53  return current.value;
54  }
55  }
56 
57  public NodeEnumerator(ListDictionary list)
58  {
59  this.list = list;
60  version = list.version;
61  start = true;
62  current = null;
63  }
64 
65  public bool MoveNext()
66  {
67  if (version != list.version)
68  {
69  throw new InvalidOperationException(SR.GetString("InvalidOperation_EnumFailedVersion"));
70  }
71  if (start)
72  {
73  current = list.head;
74  start = false;
75  }
76  else if (current != null)
77  {
78  current = current.next;
79  }
80  return current != null;
81  }
82 
83  public void Reset()
84  {
85  if (version != list.version)
86  {
87  throw new InvalidOperationException(SR.GetString("InvalidOperation_EnumFailedVersion"));
88  }
89  start = true;
90  current = null;
91  }
92  }
93 
94  private class NodeKeyValueCollection : ICollection, IEnumerable
95  {
96  private class NodeKeyValueEnumerator : IEnumerator
97  {
98  private ListDictionary list;
99 
100  private DictionaryNode current;
101 
102  private int version;
103 
104  private bool isKeys;
105 
106  private bool start;
107 
108  public object Current
109  {
110  get
111  {
112  if (current == null)
113  {
114  throw new InvalidOperationException(SR.GetString("InvalidOperation_EnumOpCantHappen"));
115  }
116  if (!isKeys)
117  {
118  return current.value;
119  }
120  return current.key;
121  }
122  }
123 
124  public NodeKeyValueEnumerator(ListDictionary list, bool isKeys)
125  {
126  this.list = list;
127  this.isKeys = isKeys;
128  version = list.version;
129  start = true;
130  current = null;
131  }
132 
133  public bool MoveNext()
134  {
135  if (version != list.version)
136  {
137  throw new InvalidOperationException(SR.GetString("InvalidOperation_EnumFailedVersion"));
138  }
139  if (start)
140  {
141  current = list.head;
142  start = false;
143  }
144  else if (current != null)
145  {
146  current = current.next;
147  }
148  return current != null;
149  }
150 
151  public void Reset()
152  {
153  if (version != list.version)
154  {
155  throw new InvalidOperationException(SR.GetString("InvalidOperation_EnumFailedVersion"));
156  }
157  start = true;
158  current = null;
159  }
160  }
161 
162  private ListDictionary list;
163 
164  private bool isKeys;
165 
166  int ICollection.Count
167  {
168  get
169  {
170  int num = 0;
171  for (DictionaryNode dictionaryNode = list.head; dictionaryNode != null; dictionaryNode = dictionaryNode.next)
172  {
173  num++;
174  }
175  return num;
176  }
177  }
178 
180  {
181  get
182  {
183  return false;
184  }
185  }
186 
187  object ICollection.SyncRoot
188  {
189  get
190  {
191  return list.SyncRoot;
192  }
193  }
194 
195  public NodeKeyValueCollection(ListDictionary list, bool isKeys)
196  {
197  this.list = list;
198  this.isKeys = isKeys;
199  }
200 
201  void ICollection.CopyTo(Array array, int index)
202  {
203  if (array == null)
204  {
205  throw new ArgumentNullException("array");
206  }
207  if (index < 0)
208  {
209  throw new ArgumentOutOfRangeException("index", SR.GetString("ArgumentOutOfRange_NeedNonNegNum"));
210  }
211  for (DictionaryNode dictionaryNode = list.head; dictionaryNode != null; dictionaryNode = dictionaryNode.next)
212  {
213  array.SetValue(isKeys ? dictionaryNode.key : dictionaryNode.value, index);
214  index++;
215  }
216  }
217 
219  {
220  return new NodeKeyValueEnumerator(list, isKeys);
221  }
222  }
223 
224  [Serializable]
225  private class DictionaryNode
226  {
227  public object key;
228 
229  public object value;
230 
231  public DictionaryNode next;
232  }
233 
234  private DictionaryNode head;
235 
236  private int version;
237 
238  private int count;
239 
240  private IComparer comparer;
241 
242  [NonSerialized]
243  private object _syncRoot;
244 
250  public object this[object key]
251  {
252  get
253  {
254  if (key == null)
255  {
256  throw new ArgumentNullException("key", SR.GetString("ArgumentNull_Key"));
257  }
258  DictionaryNode next = head;
259  if (comparer == null)
260  {
261  while (next != null)
262  {
263  object key2 = next.key;
264  if (key2 != null && key2.Equals(key))
265  {
266  return next.value;
267  }
268  next = next.next;
269  }
270  }
271  else
272  {
273  while (next != null)
274  {
275  object key3 = next.key;
276  if (key3 != null && comparer.Compare(key3, key) == 0)
277  {
278  return next.value;
279  }
280  next = next.next;
281  }
282  }
283  return null;
284  }
285  set
286  {
287  if (key == null)
288  {
289  throw new ArgumentNullException("key", SR.GetString("ArgumentNull_Key"));
290  }
291  version++;
292  DictionaryNode dictionaryNode = null;
293  DictionaryNode next;
294  for (next = head; next != null; next = next.next)
295  {
296  object key2 = next.key;
297  if ((comparer == null) ? key2.Equals(key) : (comparer.Compare(key2, key) == 0))
298  {
299  break;
300  }
301  dictionaryNode = next;
302  }
303  if (next != null)
304  {
305  next.value = value;
306  return;
307  }
308  DictionaryNode dictionaryNode2 = new DictionaryNode();
309  dictionaryNode2.key = key;
310  dictionaryNode2.value = value;
311  if (dictionaryNode != null)
312  {
313  dictionaryNode.next = dictionaryNode2;
314  }
315  else
316  {
317  head = dictionaryNode2;
318  }
319  count++;
320  }
321  }
322 
325  public int Count => count;
326 
329  public ICollection Keys => new NodeKeyValueCollection(this, isKeys: true);
330 
333  public bool IsReadOnly => false;
334 
337  public bool IsFixedSize => false;
338 
341  public bool IsSynchronized => false;
342 
345  public object SyncRoot
346  {
347  get
348  {
349  if (_syncRoot == null)
350  {
351  Interlocked.CompareExchange(ref _syncRoot, new object(), null);
352  }
353  return _syncRoot;
354  }
355  }
356 
359  public ICollection Values => new NodeKeyValueCollection(this, isKeys: false);
360 
362  public ListDictionary()
363  {
364  }
365 
369  public ListDictionary(IComparer comparer)
370  {
371  this.comparer = comparer;
372  }
373 
380  public void Add(object key, object value)
381  {
382  if (key == null)
383  {
384  throw new ArgumentNullException("key", SR.GetString("ArgumentNull_Key"));
385  }
386  version++;
387  DictionaryNode dictionaryNode = null;
388  for (DictionaryNode next = head; next != null; next = next.next)
389  {
390  object key2 = next.key;
391  if ((comparer == null) ? key2.Equals(key) : (comparer.Compare(key2, key) == 0))
392  {
393  throw new ArgumentException(SR.GetString("Argument_AddingDuplicate"));
394  }
395  dictionaryNode = next;
396  }
397  DictionaryNode dictionaryNode2 = new DictionaryNode();
398  dictionaryNode2.key = key;
399  dictionaryNode2.value = value;
400  if (dictionaryNode != null)
401  {
402  dictionaryNode.next = dictionaryNode2;
403  }
404  else
405  {
406  head = dictionaryNode2;
407  }
408  count++;
409  }
410 
412  public void Clear()
413  {
414  count = 0;
415  head = null;
416  version++;
417  }
418 
425  public bool Contains(object key)
426  {
427  if (key == null)
428  {
429  throw new ArgumentNullException("key", SR.GetString("ArgumentNull_Key"));
430  }
431  for (DictionaryNode next = head; next != null; next = next.next)
432  {
433  object key2 = next.key;
434  if ((comparer == null) ? key2.Equals(key) : (comparer.Compare(key2, key) == 0))
435  {
436  return true;
437  }
438  }
439  return false;
440  }
441 
452  public void CopyTo(Array array, int index)
453  {
454  if (array == null)
455  {
456  throw new ArgumentNullException("array");
457  }
458  if (index < 0)
459  {
460  throw new ArgumentOutOfRangeException("index", SR.GetString("ArgumentOutOfRange_NeedNonNegNum"));
461  }
462  if (array.Length - index < count)
463  {
464  throw new ArgumentException(SR.GetString("Arg_InsufficientSpace"));
465  }
466  for (DictionaryNode next = head; next != null; next = next.next)
467  {
468  array.SetValue(new DictionaryEntry(next.key, next.value), index);
469  index++;
470  }
471  }
472 
476  {
477  return new NodeEnumerator(this);
478  }
479 
483  {
484  return new NodeEnumerator(this);
485  }
486 
491  public void Remove(object key)
492  {
493  if (key == null)
494  {
495  throw new ArgumentNullException("key", SR.GetString("ArgumentNull_Key"));
496  }
497  version++;
498  DictionaryNode dictionaryNode = null;
499  DictionaryNode next;
500  for (next = head; next != null; next = next.next)
501  {
502  object key2 = next.key;
503  if ((comparer == null) ? key2.Equals(key) : (comparer.Compare(key2, key) == 0))
504  {
505  break;
506  }
507  dictionaryNode = next;
508  }
509  if (next != null)
510  {
511  if (next == head)
512  {
513  head = next.next;
514  }
515  else
516  {
517  dictionaryNode.next = next.next;
518  }
519  count--;
520  }
521  }
522  }
523 }
object SyncRoot
Gets an object that can be used to synchronize access to the T:System.Collections....
Definition: ICollection.cs:23
The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method th...
void CopyTo(Array array, int index)
Copies the T:System.Collections.Specialized.ListDictionary entries to a one-dimensional T:System....
object SyncRoot
Gets an object that can be used to synchronize access to the T:System.Collections....
void Add(object key, object value)
Adds an entry with the specified key and value into the T:System.Collections.Specialized....
Definition: __Canon.cs:3
The exception that is thrown when the value of an argument is outside the allowable range of values a...
bool IsSynchronized
Gets a value indicating whether the T:System.Collections.Specialized.ListDictionary is synchronized (...
ListDictionary(IComparer comparer)
Creates an empty T:System.Collections.Specialized.ListDictionary using the specified comparer.
int Count
Gets the number of key/value pairs contained in the T:System.Collections.Specialized....
int Compare(object x, object y)
Compares two objects and returns a value indicating whether one is less than, equal to,...
Exposes an enumerator, which supports a simple iteration over a non-generic collection....
Definition: IEnumerable.cs:9
ICollection Keys
Gets an T:System.Collections.ICollection containing the keys in the T:System.Collections....
void Remove(object key)
Removes the entry with the specified key from the T:System.Collections.Specialized....
bool Contains(object key)
Determines whether the T:System.Collections.Specialized.ListDictionary contains a specific key.
static int CompareExchange(ref int location1, int value, int comparand)
Compares two 32-bit signed integers for equality and, if they are equal, replaces the first value.
Exposes a method that compares two objects.
Definition: IComparer.cs:8
Provides methods for creating, manipulating, searching, and sorting arrays, thereby serving as the ba...
Definition: Array.cs:17
bool IsSynchronized
Gets a value indicating whether access to the T:System.Collections.ICollection is synchronized (threa...
Definition: ICollection.cs:33
IEnumerator GetEnumerator()
Returns an enumerator that iterates through a collection.
The exception that is thrown when one of the arguments provided to a method is not valid.
bool IsFixedSize
Gets a value indicating whether the T:System.Collections.Specialized.ListDictionary has a fixed size.
void Clear()
Removes all entries from the T:System.Collections.Specialized.ListDictionary.
Specifies that the class can be serialized.
Enumerates the elements of a nongeneric dictionary.
The exception that is thrown when a method call is invalid for the object's current state.
int Count
Gets the number of elements contained in the T:System.Collections.ICollection.
Definition: ICollection.cs:14
bool IsReadOnly
Gets a value indicating whether the T:System.Collections.Specialized.ListDictionary is read-only.
Defines size, enumerators, and synchronization methods for all nongeneric collections.
Definition: ICollection.cs:8
void CopyTo(Array array, int index)
Copies the elements of the T:System.Collections.ICollection to an T:System.Array, starting at a parti...
Defines a dictionary key/value pair that can be set or retrieved.
Represents a nongeneric collection of key/value pairs.
Definition: IDictionary.cs:8
Provides atomic operations for variables that are shared by multiple threads.
Definition: Interlocked.cs:10
ListDictionary()
Creates an empty T:System.Collections.Specialized.ListDictionary using the default comparer.
Supports a simple iteration over a non-generic collection.
Definition: IEnumerator.cs:9
ICollection Values
Gets an T:System.Collections.ICollection containing the values in the T:System.Collections....
Implements IDictionary using a singly linked list. Recommended for collections that typically include...
IDictionaryEnumerator GetEnumerator()
Returns an T:System.Collections.IDictionaryEnumerator that iterates through the T:System....