The Labs \ Source Viewer \ SSCLI \ System.Collections.Generic \ SortedDictionary

  1. //------------------------------------------------------------------------------
  2. // <copyright file="SortedDictionary.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. namespace System.Collections.Generic
  16. {
  17.     using System;
  18.     using System.Diagnostics;
  19.     using System.Runtime.Serialization;
  20.    
  21.     [Serializable()]
  22.     [DebuggerTypeProxy(typeof(System_DictionaryDebugView<, >))]
  23.     [DebuggerDisplay("Count = {Count}")]
  24.     public class SortedDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary
  25.     {
  26.         [NonSerialized()]
  27.         private KeyCollection keys;
  28.        
  29.         [NonSerialized()]
  30.         private ValueCollection values;
  31.        
  32.         private TreeSet<KeyValuePair<TKey, TValue>> _set;
  33.        
  34.         public SortedDictionary() : this((IComparer<TKey>)null)
  35.         {
  36.         }
  37.        
  38.         public SortedDictionary(IDictionary<TKey, TValue> dictionary) : this(dictionary, null)
  39.         {
  40.         }
  41.        
  42.         public SortedDictionary(IDictionary<TKey, TValue> dictionary, IComparer<TKey> comparer)
  43.         {
  44.             if (dictionary == null) {
  45.                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.dictionary);
  46.             }
  47.            
  48.             _set = new TreeSet<KeyValuePair<TKey, TValue>>(new KeyValuePairComparer(comparer));
  49.            
  50.             foreach (KeyValuePair<TKey, TValue> pair in dictionary) {
  51.                 _set.Add(pair);
  52.             }
  53.         }
  54.        
  55.         public SortedDictionary(IComparer<TKey> comparer)
  56.         {
  57.             _set = new TreeSet<KeyValuePair<TKey, TValue>>(new KeyValuePairComparer(comparer));
  58.         }
  59.        
  60.         void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> keyValuePair)
  61.         {
  62.             _set.Add(keyValuePair);
  63.         }
  64.        
  65.         bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> keyValuePair)
  66.         {
  67.             TreeSet<KeyValuePair<TKey, TValue>>.Node node = _set.FindNode(keyValuePair);
  68.             if (node == null) {
  69.                 return false;
  70.             }
  71.            
  72.             if (keyValuePair.Value == null) {
  73.                 return node.Item.Value == null;
  74.             }
  75.             else {
  76.                 return EqualityComparer<TValue>.Default.Equals(node.Item.Value, keyValuePair.Value);
  77.             }
  78.         }
  79.        
  80.         bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> keyValuePair)
  81.         {
  82.             TreeSet<KeyValuePair<TKey, TValue>>.Node node = _set.FindNode(keyValuePair);
  83.             if (node == null) {
  84.                 return false;
  85.             }
  86.            
  87.             if (EqualityComparer<TValue>.Default.Equals(node.Item.Value, keyValuePair.Value)) {
  88.                 _set.Remove(keyValuePair);
  89.                 return true;
  90.             }
  91.             return false;
  92.         }
  93.        
  94.         bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly {
  95.             get { return false; }
  96.         }
  97.        
  98.         public TValue this[TKey key]
  99.         {
  100.             get {
  101.                 if (key == null) {
  102.                     ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
  103.                 }
  104.                
  105.                 TreeSet<KeyValuePair<TKey, TValue>>.Node node = _set.FindNode(new KeyValuePair<TKey, TValue>(key, default(TValue)));
  106.                 if (node == null) {
  107.                     ThrowHelper.ThrowKeyNotFoundException();
  108.                 }
  109.                
  110.                 return node.Item.Value;
  111.             }
  112.             set {
  113.                 if (key == null) {
  114.                     ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
  115.                 }
  116.                
  117.                 TreeSet<KeyValuePair<TKey, TValue>>.Node node = _set.FindNode(new KeyValuePair<TKey, TValue>(key, default(TValue)));
  118.                 if (node == null) {
  119.                     _set.Add(new KeyValuePair<TKey, TValue>(key, value));
  120.                 }
  121.                 else {
  122.                     node.Item = new KeyValuePair<TKey, TValue>(node.Item.Key, value);
  123.                     _set.UpdateVersion();
  124.                 }
  125.             }
  126.         }
  127.        
  128.         public int Count {
  129.             get { return _set.Count; }
  130.         }
  131.        
  132.         public IComparer<TKey> Comparer {
  133.             get { return ((KeyValuePairComparer)_set.Comparer).keyComparer; }
  134.         }
  135.        
  136.         public KeyCollection Keys {
  137.             get {
  138.                 if (keys == null)
  139.                     keys = new KeyCollection(this);
  140.                 return keys;
  141.             }
  142.         }
  143.        
  144.         ICollection<TKey> IDictionary<TKey, TValue>.Keys {
  145.             get { return Keys; }
  146.         }
  147.        
  148.         public ValueCollection Values {
  149.             get {
  150.                 if (values == null)
  151.                     values = new ValueCollection(this);
  152.                 return values;
  153.             }
  154.         }
  155.        
  156.         ICollection<TValue> IDictionary<TKey, TValue>.Values {
  157.             get { return Values; }
  158.         }
  159.        
  160.         public void Add(TKey key, TValue value)
  161.         {
  162.             if (key == null) {
  163.                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
  164.             }
  165.             _set.Add(new KeyValuePair<TKey, TValue>(key, value));
  166.         }
  167.        
  168.         public void Clear()
  169.         {
  170.             _set.Clear();
  171.         }
  172.        
  173.         public bool ContainsKey(TKey key)
  174.         {
  175.             if (key == null) {
  176.                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
  177.             }
  178.            
  179.             return _set.Contains(new KeyValuePair<TKey, TValue>(key, default(TValue)));
  180.         }
  181.        
  182.         public bool ContainsValue(TValue value)
  183.         {
  184.             bool found = false;
  185.             if (value == null) {
  186.                 _set.InOrderTreeWalk(delegate(TreeSet<KeyValuePair<TKey, TValue>>.Node node)
  187.                 {
  188.                     if (node.Item.Value == null) {
  189.                         found = true;
  190.                         return false;
  191.                         // stop the walk
  192.                     }
  193.                     return true;
  194.                 }
  195. );
  196.                
  197.             }
  198.             else {
  199.                 EqualityComparer<TValue> valueComparer = EqualityComparer<TValue>.Default;
  200.                 _set.InOrderTreeWalk(delegate(TreeSet<KeyValuePair<TKey, TValue>>.Node node)
  201.                 {
  202.                     if (valueComparer.Equals(node.Item.Value, value)) {
  203.                         found = true;
  204.                         return false;
  205.                         // stop the walk
  206.                     }
  207.                     return true;
  208.                 }
  209. );
  210.             }
  211.             return found;
  212.         }
  213.        
  214.         public void CopyTo(KeyValuePair<TKey, TValue>[] array, int index)
  215.         {
  216.             _set.CopyTo(array, index);
  217.         }
  218.        
  219.         public Enumerator GetEnumerator()
  220.         {
  221.             return new Enumerator(this, Enumerator.KeyValuePair);
  222.         }
  223.        
  224.         IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
  225.         {
  226.             return new Enumerator(this, Enumerator.KeyValuePair);
  227.         }
  228.        
  229.         public bool Remove(TKey key)
  230.         {
  231.             if (key == null) {
  232.                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
  233.             }
  234.            
  235.             return _set.Remove(new KeyValuePair<TKey, TValue>(key, default(TValue)));
  236.         }
  237.        
  238.         public bool TryGetValue(TKey key, out TValue value)
  239.         {
  240.             if (key == null) {
  241.                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
  242.             }
  243.            
  244.             TreeSet<KeyValuePair<TKey, TValue>>.Node node = _set.FindNode(new KeyValuePair<TKey, TValue>(key, default(TValue)));
  245.             if (node == null) {
  246.                 value = default(TValue);
  247.                 return false;
  248.             }
  249.             value = node.Item.Value;
  250.             return true;
  251.         }
  252.        
  253.         void ICollection.CopyTo(Array array, int index)
  254.         {
  255.             ((ICollection)_set).CopyTo(array, index);
  256.         }
  257.        
  258.         bool IDictionary.IsFixedSize {
  259.             get { return false; }
  260.         }
  261.        
  262.         bool IDictionary.IsReadOnly {
  263.             get { return false; }
  264.         }
  265.        
  266.         ICollection IDictionary.Keys {
  267.             get { return (ICollection)Keys; }
  268.         }
  269.        
  270.         ICollection IDictionary.Values {
  271.             get { return (ICollection)Values; }
  272.         }
  273.        
  274.         object IDictionary.this[object key]
  275.         {
  276.             get {
  277.                 if (IsCompatibleKey(key)) {
  278.                     TValue value;
  279.                     if (TryGetValue((TKey)key, out value)) {
  280.                         return value;
  281.                     }
  282.                 }
  283.                 return null;
  284.             }
  285.             set {
  286.                 VerifyKey(key);
  287.                 VerifyValueType(value);
  288.                 this[(TKey)key] = (TValue)value;
  289.             }
  290.         }
  291.        
  292.         void IDictionary.Add(object key, object value)
  293.         {
  294.             VerifyKey(key);
  295.             VerifyValueType(value);
  296.             Add((TKey)key, (TValue)value);
  297.         }
  298.        
  299.         bool IDictionary.Contains(object key)
  300.         {
  301.             if (IsCompatibleKey(key)) {
  302.                 return ContainsKey((TKey)key);
  303.             }
  304.             return false;
  305.         }
  306.        
  307.         private static void VerifyKey(object key)
  308.         {
  309.             if (key == null) {
  310.                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
  311.             }
  312.            
  313.             if (!(key is TKey)) {
  314.                 ThrowHelper.ThrowWrongKeyTypeArgumentException(key, typeof(TKey));
  315.             }
  316.         }
  317.        
  318.         private static bool IsCompatibleKey(object key)
  319.         {
  320.             if (key == null) {
  321.                 ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
  322.             }
  323.            
  324.             return (key is TKey);
  325.         }
  326.        
  327.         private static void VerifyValueType(object value)
  328.         {
  329.             if ((value is TValue) || (value == null && !typeof(TValue).IsValueType)) {
  330.                 return;
  331.             }
  332.             ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(TValue));
  333.         }
  334.        
  335.         IDictionaryEnumerator IDictionary.GetEnumerator()
  336.         {
  337.             return new Enumerator(this, Enumerator.DictEntry);
  338.         }
  339.        
  340.         void IDictionary.Remove(object key)
  341.         {
  342.             if (IsCompatibleKey(key)) {
  343.                 Remove((TKey)key);
  344.             }
  345.         }
  346.        
  347.         bool ICollection.IsSynchronized {
  348.             get { return false; }
  349.         }
  350.        
  351.         object ICollection.SyncRoot {
  352.             get { return ((ICollection)_set).SyncRoot; }
  353.         }
  354.        
  355.         IEnumerator IEnumerable.GetEnumerator()
  356.         {
  357.             return new Enumerator(this, Enumerator.KeyValuePair);
  358.         }
  359.        
  360.         public struct Enumerator : IEnumerator<KeyValuePair<TKey, TValue>>, IDictionaryEnumerator
  361.         {
  362.             private TreeSet<KeyValuePair<TKey, TValue>>.Enumerator treeEnum;
  363.             private int getEnumeratorRetType;
  364.             // What should Enumerator.Current return?
  365.             internal const int KeyValuePair = 1;
  366.             internal const int DictEntry = 2;
  367.            
  368.             internal Enumerator(SortedDictionary<TKey, TValue> dictionary, int getEnumeratorRetType)
  369.             {
  370.                 treeEnum = dictionary._set.GetEnumerator();
  371.                 this.getEnumeratorRetType = getEnumeratorRetType;
  372.             }
  373.            
  374.             public bool MoveNext()
  375.             {
  376.                 return treeEnum.MoveNext();
  377.             }
  378.            
  379.             public void Dispose()
  380.             {
  381.                 treeEnum.Dispose();
  382.             }
  383.            
  384.             public KeyValuePair<TKey, TValue> Current {
  385.                 get { return treeEnum.Current; }
  386.             }
  387.            
  388.             internal bool NotStartedOrEnded {
  389.                 get { return treeEnum.NotStartedOrEnded; }
  390.             }
  391.            
  392.             internal void Reset()
  393.             {
  394.                 treeEnum.Reset();
  395.             }
  396.            
  397.            
  398.             void IEnumerator.Reset()
  399.             {
  400.                 treeEnum.Reset();
  401.             }
  402.            
  403.             object IEnumerator.Current {
  404.                 get {
  405.                     if (NotStartedOrEnded) {
  406.                         ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
  407.                     }
  408.                    
  409.                     if (getEnumeratorRetType == DictEntry) {
  410.                         return new DictionaryEntry(Current.Key, Current.Value);
  411.                     }
  412.                     else {
  413.                         return new KeyValuePair<TKey, TValue>(Current.Key, Current.Value);
  414.                     }
  415.                    
  416.                 }
  417.             }
  418.            
  419.             object IDictionaryEnumerator.Key {
  420.                 get {
  421.                     if (NotStartedOrEnded) {
  422.                         ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
  423.                     }
  424.                    
  425.                     return Current.Key;
  426.                 }
  427.             }
  428.            
  429.             object IDictionaryEnumerator.Value {
  430.                 get {
  431.                     if (NotStartedOrEnded) {
  432.                         ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
  433.                     }
  434.                    
  435.                     return Current.Value;
  436.                 }
  437.             }
  438.            
  439.             DictionaryEntry IDictionaryEnumerator.Entry {
  440.                 get {
  441.                     if (NotStartedOrEnded) {
  442.                         ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
  443.                     }
  444.                    
  445.                     return new DictionaryEntry(Current.Key, Current.Value);
  446.                 }
  447.             }
  448.         }
  449.        
  450.         [DebuggerTypeProxy(typeof(System_DictionaryKeyCollectionDebugView<, >))]
  451.         [DebuggerDisplay("Count = {Count}")]
  452.         [Serializable()]
  453.         public sealed class KeyCollection : ICollection<TKey>, ICollection
  454.         {
  455.             private SortedDictionary<TKey, TValue> dictionary;
  456.            
  457.             public KeyCollection(SortedDictionary<TKey, TValue> dictionary)
  458.             {
  459.                 if (dictionary == null) {
  460.                     ThrowHelper.ThrowArgumentNullException(ExceptionArgument.dictionary);
  461.                 }
  462.                 this.dictionary = dictionary;
  463.             }
  464.            
  465.             public Enumerator GetEnumerator()
  466.             {
  467.                 return new Enumerator(dictionary);
  468.             }
  469.            
  470.             IEnumerator<TKey> IEnumerable<TKey>.GetEnumerator()
  471.             {
  472.                 return new Enumerator(dictionary);
  473.             }
  474.            
  475.             IEnumerator IEnumerable.GetEnumerator()
  476.             {
  477.                 return new Enumerator(dictionary);
  478.             }
  479.            
  480.             public void CopyTo(TKey[] array, int index)
  481.             {
  482.                 if (array == null) {
  483.                     ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
  484.                 }
  485.                
  486.                 if (index < 0) {
  487.                     ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index);
  488.                 }
  489.                
  490.                 if (array.Length - index < Count) {
  491.                     ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
  492.                 }
  493.                
  494.                 dictionary._set.InOrderTreeWalk(delegate(TreeSet<KeyValuePair<TKey, TValue>>.Node node)
  495.                 {
  496.                     array[index++] = node.Item.Key;
  497.                     return true;
  498.                 }
  499. );
  500.             }
  501.            
  502.             void ICollection.CopyTo(Array array, int index)
  503.             {
  504.                 if (array == null) {
  505.                     ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
  506.                 }
  507.                
  508.                 if (array.Rank != 1) {
  509.                     ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
  510.                 }
  511.                
  512.                 if (array.GetLowerBound(0) != 0) {
  513.                     ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
  514.                 }
  515.                
  516.                 if (index < 0) {
  517.                     ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.arrayIndex, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
  518.                 }
  519.                
  520.                 if (array.Length - index < dictionary.Count) {
  521.                     ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
  522.                 }
  523.                
  524.                 TKey[] keys = array as TKey[];
  525.                 if (keys != null) {
  526.                     CopyTo(keys, index);
  527.                 }
  528.                 else {
  529.                     object[] objects = (object[])array;
  530.                     if (objects == null) {
  531.                         ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
  532.                     }
  533.                    
  534.                     try {
  535.                         dictionary._set.InOrderTreeWalk(delegate(TreeSet<KeyValuePair<TKey, TValue>>.Node node)
  536.                         {
  537.                             objects[index++] = node.Item.Key;
  538.                             return true;
  539.                         }
  540. );
  541.                     }
  542.                     catch (ArrayTypeMismatchException) {
  543.                         ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
  544.                     }
  545.                 }
  546.             }
  547.            
  548.             public int Count {
  549.                 get { return dictionary.Count; }
  550.             }
  551.            
  552.             bool ICollection<TKey>.IsReadOnly {
  553.                 get { return true; }
  554.             }
  555.            
  556.             void ICollection<TKey>.Add(TKey item)
  557.             {
  558.                 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_KeyCollectionSet);
  559.             }
  560.            
  561.             void ICollection<TKey>.Clear()
  562.             {
  563.                 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_KeyCollectionSet);
  564.             }
  565.            
  566.             bool ICollection<TKey>.Contains(TKey item)
  567.             {
  568.                 return dictionary.ContainsKey(item);
  569.             }
  570.            
  571.             bool ICollection<TKey>.Remove(TKey item)
  572.             {
  573.                 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_KeyCollectionSet);
  574.                 return false;
  575.             }
  576.            
  577.             bool ICollection.IsSynchronized {
  578.                 get { return false; }
  579.             }
  580.            
  581.             object ICollection.SyncRoot {
  582.                 get { return ((ICollection)dictionary).SyncRoot; }
  583.             }
  584.            
  585.             public struct Enumerator : IEnumerator<TKey>, IEnumerator
  586.             {
  587.                 private SortedDictionary<TKey, TValue>.Enumerator dictEnum;
  588.                
  589.                 internal Enumerator(SortedDictionary<TKey, TValue> dictionary)
  590.                 {
  591.                     dictEnum = dictionary.GetEnumerator();
  592.                 }
  593.                
  594.                 public void Dispose()
  595.                 {
  596.                     dictEnum.Dispose();
  597.                 }
  598.                
  599.                 public bool MoveNext()
  600.                 {
  601.                     return dictEnum.MoveNext();
  602.                 }
  603.                
  604.                 public TKey Current {
  605.                     get { return dictEnum.Current.Key; }
  606.                 }
  607.                
  608.                 object IEnumerator.Current {
  609.                     get {
  610.                         if (dictEnum.NotStartedOrEnded) {
  611.                             ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
  612.                         }
  613.                        
  614.                         return Current;
  615.                     }
  616.                 }
  617.                
  618.                 void IEnumerator.Reset()
  619.                 {
  620.                     dictEnum.Reset();
  621.                 }
  622.                
  623.             }
  624.         }
  625.        
  626.         [DebuggerTypeProxy(typeof(System_DictionaryValueCollectionDebugView<, >))]
  627.         [DebuggerDisplay("Count = {Count}")]
  628.         [Serializable()]
  629.         public sealed class ValueCollection : ICollection<TValue>, ICollection
  630.         {
  631.             private SortedDictionary<TKey, TValue> dictionary;
  632.            
  633.             public ValueCollection(SortedDictionary<TKey, TValue> dictionary)
  634.             {
  635.                 if (dictionary == null) {
  636.                     ThrowHelper.ThrowArgumentNullException(ExceptionArgument.dictionary);
  637.                 }
  638.                 this.dictionary = dictionary;
  639.             }
  640.            
  641.             public Enumerator GetEnumerator()
  642.             {
  643.                 return new Enumerator(dictionary);
  644.             }
  645.            
  646.             IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator()
  647.             {
  648.                 return new Enumerator(dictionary);
  649.             }
  650.            
  651.             IEnumerator IEnumerable.GetEnumerator()
  652.             {
  653.                 return new Enumerator(dictionary);
  654.             }
  655.            
  656.             public void CopyTo(TValue[] array, int index)
  657.             {
  658.                 if (array == null) {
  659.                     ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
  660.                 }
  661.                
  662.                 if (index < 0) {
  663.                     ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index);
  664.                 }
  665.                
  666.                 if (array.Length - index < Count) {
  667.                     ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
  668.                 }
  669.                
  670.                 dictionary._set.InOrderTreeWalk(delegate(TreeSet<KeyValuePair<TKey, TValue>>.Node node)
  671.                 {
  672.                     array[index++] = node.Item.Value;
  673.                     return true;
  674.                 }
  675. );
  676.             }
  677.            
  678.             void ICollection.CopyTo(Array array, int index)
  679.             {
  680.                 if (array == null) {
  681.                     ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
  682.                 }
  683.                
  684.                 if (array.Rank != 1) {
  685.                     ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
  686.                 }
  687.                
  688.                 if (array.GetLowerBound(0) != 0) {
  689.                     ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
  690.                 }
  691.                
  692.                 if (index < 0) {
  693.                     ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.arrayIndex, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
  694.                 }
  695.                
  696.                 if (array.Length - index < dictionary.Count) {
  697.                     ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
  698.                 }
  699.                
  700.                 TValue[] values = array as TValue[];
  701.                 if (values != null) {
  702.                     CopyTo(values, index);
  703.                 }
  704.                 else {
  705.                     object[] objects = (object[])array;
  706.                     if (objects == null) {
  707.                         ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
  708.                     }
  709.                    
  710.                     try {
  711.                         dictionary._set.InOrderTreeWalk(delegate(TreeSet<KeyValuePair<TKey, TValue>>.Node node)
  712.                         {
  713.                             objects[index++] = node.Item.Value;
  714.                             return true;
  715.                         }
  716. );
  717.                     }
  718.                     catch (ArrayTypeMismatchException) {
  719.                         ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
  720.                     }
  721.                 }
  722.             }
  723.            
  724.             public int Count {
  725.                 get { return dictionary.Count; }
  726.             }
  727.            
  728.             bool ICollection<TValue>.IsReadOnly {
  729.                 get { return true; }
  730.             }
  731.            
  732.             void ICollection<TValue>.Add(TValue item)
  733.             {
  734.                 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ValueCollectionSet);
  735.             }
  736.            
  737.             void ICollection<TValue>.Clear()
  738.             {
  739.                 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ValueCollectionSet);
  740.             }
  741.            
  742.             bool ICollection<TValue>.Contains(TValue item)
  743.             {
  744.                 return dictionary.ContainsValue(item);
  745.             }
  746.            
  747.             bool ICollection<TValue>.Remove(TValue item)
  748.             {
  749.                 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ValueCollectionSet);
  750.                 return false;
  751.             }
  752.            
  753.             bool ICollection.IsSynchronized {
  754.                 get { return false; }
  755.             }
  756.            
  757.             object ICollection.SyncRoot {
  758.                 get { return ((ICollection)dictionary).SyncRoot; }
  759.             }
  760.            
  761.             public struct Enumerator : IEnumerator<TValue>, IEnumerator
  762.             {
  763.                 private SortedDictionary<TKey, TValue>.Enumerator dictEnum;
  764.                
  765.                 internal Enumerator(SortedDictionary<TKey, TValue> dictionary)
  766.                 {
  767.                     dictEnum = dictionary.GetEnumerator();
  768.                 }
  769.                
  770.                 public void Dispose()
  771.                 {
  772.                     dictEnum.Dispose();
  773.                 }
  774.                
  775.                 public bool MoveNext()
  776.                 {
  777.                     return dictEnum.MoveNext();
  778.                 }
  779.                
  780.                 public TValue Current {
  781.                     get { return dictEnum.Current.Value; }
  782.                 }
  783.                
  784.                 object IEnumerator.Current {
  785.                     get {
  786.                         if (dictEnum.NotStartedOrEnded) {
  787.                             ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
  788.                         }
  789.                        
  790.                         return Current;
  791.                     }
  792.                 }
  793.                
  794.                 void IEnumerator.Reset()
  795.                 {
  796.                     dictEnum.Reset();
  797.                 }
  798.             }
  799.         }
  800.        
  801.         [Serializable()]
  802.         internal class KeyValuePairComparer : Comparer<KeyValuePair<TKey, TValue>>
  803.         {
  804.             internal IComparer<TKey> keyComparer;
  805.            
  806.             public KeyValuePairComparer(IComparer<TKey> keyComparer)
  807.             {
  808.                 if (keyComparer == null) {
  809.                     this.keyComparer = Comparer<TKey>.Default;
  810.                 }
  811.                 else {
  812.                     this.keyComparer = keyComparer;
  813.                 }
  814.             }
  815.            
  816.             public override int Compare(KeyValuePair<TKey, TValue> x, KeyValuePair<TKey, TValue> y)
  817.             {
  818.                 return keyComparer.Compare(x.Key, y.Key);
  819.             }
  820.         }
  821.     }
  822. }

Developer Fusion