PageRenderTime 67ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/mcs/class/corlib/System.Collections/SortedList.cs

https://bitbucket.org/danipen/mono
C# | 1215 lines | 841 code | 280 blank | 94 comment | 118 complexity | 0dceb3a0367e611a065a5fafa288b43a MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  1. //
  2. // System.Collections.SortedList.cs
  3. //
  4. // Author:
  5. // Sergey Chaban (serge@wildwestsoftware.com)
  6. // Duncan Mak (duncan@ximian.com)
  7. // Herve Poussineau (hpoussineau@fr.st
  8. //
  9. //
  10. // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
  11. //
  12. // Permission is hereby granted, free of charge, to any person obtaining
  13. // a copy of this software and associated documentation files (the
  14. // "Software"), to deal in the Software without restriction, including
  15. // without limitation the rights to use, copy, modify, merge, publish,
  16. // distribute, sublicense, and/or sell copies of the Software, and to
  17. // permit persons to whom the Software is furnished to do so, subject to
  18. // the following conditions:
  19. //
  20. // The above copyright notice and this permission notice shall be
  21. // included in all copies or substantial portions of the Software.
  22. //
  23. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  27. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  28. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  29. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  30. //
  31. using System.Globalization;
  32. using System.Runtime.InteropServices;
  33. using System.Diagnostics;
  34. namespace System.Collections {
  35. /// <summary>
  36. /// Represents a collection of associated keys and values
  37. /// that are sorted by the keys and are accessible by key
  38. /// and by index.
  39. /// </summary>
  40. [Serializable]
  41. [ComVisible(true)]
  42. [DebuggerDisplay ("Count={Count}")]
  43. [DebuggerTypeProxy (typeof (CollectionDebuggerView))]
  44. public class SortedList : IDictionary, ICollection,
  45. IEnumerable, ICloneable {
  46. [Serializable]
  47. internal struct Slot {
  48. internal Object key;
  49. internal Object value;
  50. }
  51. const int INITIAL_SIZE = 16;
  52. private enum EnumeratorMode : int { KEY_MODE = 0, VALUE_MODE, ENTRY_MODE }
  53. private Slot[] table;
  54. private IComparer comparer;
  55. private int inUse;
  56. private int modificationCount;
  57. private int defaultCapacity;
  58. //
  59. // Constructors
  60. //
  61. public SortedList ()
  62. : this (null, INITIAL_SIZE)
  63. {
  64. }
  65. public SortedList (int initialCapacity)
  66. : this (null, initialCapacity)
  67. {
  68. }
  69. public SortedList (IComparer comparer, int capacity)
  70. {
  71. if (capacity < 0)
  72. throw new ArgumentOutOfRangeException ("capacity");
  73. if (capacity == 0)
  74. defaultCapacity = 0;
  75. else
  76. defaultCapacity = INITIAL_SIZE;
  77. this.comparer = comparer;
  78. InitTable (capacity, true);
  79. }
  80. public SortedList (IComparer comparer)
  81. {
  82. this.comparer = comparer;
  83. InitTable (INITIAL_SIZE, true);
  84. }
  85. public SortedList (IDictionary d) : this (d, null)
  86. {
  87. }
  88. // LAMESPEC: MSDN docs talk about an InvalidCastException but
  89. // I wasn't able to duplicate such a case in the unit tests.
  90. public SortedList (IDictionary d, IComparer comparer)
  91. {
  92. if (d == null)
  93. throw new ArgumentNullException ("dictionary");
  94. InitTable (d.Count, true);
  95. this.comparer = comparer;
  96. IDictionaryEnumerator it = d.GetEnumerator ();
  97. while (it.MoveNext ()) {
  98. Add (it.Key, it.Value);
  99. }
  100. }
  101. //
  102. // Properties
  103. //
  104. // ICollection
  105. public virtual int Count {
  106. get {
  107. return inUse;
  108. }
  109. }
  110. public virtual bool IsSynchronized {
  111. get {
  112. return false;
  113. }
  114. }
  115. public virtual Object SyncRoot {
  116. get {
  117. return this;
  118. }
  119. }
  120. // IDictionary
  121. public virtual bool IsFixedSize {
  122. get {
  123. return false;
  124. }
  125. }
  126. public virtual bool IsReadOnly {
  127. get {
  128. return false;
  129. }
  130. }
  131. public virtual ICollection Keys {
  132. get {
  133. return new ListKeys (this);
  134. }
  135. }
  136. public virtual ICollection Values {
  137. get {
  138. return new ListValues (this);
  139. }
  140. }
  141. public virtual Object this [Object key] {
  142. get {
  143. if (key == null)
  144. throw new ArgumentNullException();
  145. return GetImpl (key);
  146. }
  147. set {
  148. if (key == null)
  149. throw new ArgumentNullException();
  150. if (IsReadOnly)
  151. throw new NotSupportedException("SortedList is Read Only.");
  152. if (Find(key) < 0 && IsFixedSize)
  153. throw new NotSupportedException("Key not found and SortedList is fixed size.");
  154. PutImpl (key, value, true);
  155. }
  156. }
  157. public virtual int Capacity {
  158. get {
  159. return table.Length;
  160. }
  161. set {
  162. int current = this.table.Length;
  163. if (inUse > value) {
  164. throw new ArgumentOutOfRangeException("capacity too small");
  165. }
  166. else if (value == 0) {
  167. // return to default size
  168. Slot [] newTable = new Slot [defaultCapacity];
  169. Array.Copy (table, newTable, inUse);
  170. this.table = newTable;
  171. }
  172. else if (value > inUse) {
  173. Slot [] newTable = new Slot [value];
  174. Array.Copy (table, newTable, inUse);
  175. this.table = newTable;
  176. }
  177. else if (value > current) {
  178. Slot [] newTable = new Slot [value];
  179. Array.Copy (table, newTable, current);
  180. this.table = newTable;
  181. }
  182. }
  183. }
  184. //
  185. // Public instance methods.
  186. //
  187. // IEnumerable
  188. IEnumerator IEnumerable.GetEnumerator ()
  189. {
  190. return new Enumerator (this, EnumeratorMode.ENTRY_MODE);
  191. }
  192. // IDictionary
  193. public virtual void Add (object key, object value)
  194. {
  195. PutImpl (key, value, false);
  196. }
  197. public virtual void Clear ()
  198. {
  199. Array.Clear (table, 0, table.Length);
  200. inUse = 0;
  201. modificationCount++;
  202. }
  203. public virtual bool Contains (object key)
  204. {
  205. if (null == key)
  206. throw new ArgumentNullException();
  207. try {
  208. return (Find (key) >= 0);
  209. } catch (Exception) {
  210. throw new InvalidOperationException();
  211. }
  212. }
  213. public virtual IDictionaryEnumerator GetEnumerator ()
  214. {
  215. return new Enumerator (this, EnumeratorMode.ENTRY_MODE);
  216. }
  217. public virtual void Remove (object key)
  218. {
  219. int i = IndexOfKey (key);
  220. if (i >= 0) RemoveAt (i);
  221. }
  222. // ICollection
  223. public virtual void CopyTo (Array array, int arrayIndex)
  224. {
  225. if (null == array)
  226. throw new ArgumentNullException();
  227. if (arrayIndex < 0)
  228. throw new ArgumentOutOfRangeException();
  229. if (array.Rank > 1)
  230. throw new ArgumentException("array is multi-dimensional");
  231. if (arrayIndex >= array.Length)
  232. throw new ArgumentNullException("arrayIndex is greater than or equal to array.Length");
  233. if (Count > (array.Length - arrayIndex))
  234. throw new ArgumentNullException("Not enough space in array from arrayIndex to end of array");
  235. IDictionaryEnumerator it = GetEnumerator ();
  236. int i = arrayIndex;
  237. while (it.MoveNext ()) {
  238. array.SetValue (it.Entry, i++);
  239. }
  240. }
  241. // ICloneable
  242. public virtual object Clone ()
  243. {
  244. SortedList sl = new SortedList (this, comparer);
  245. sl.modificationCount = this.modificationCount;
  246. return sl;
  247. }
  248. //
  249. // SortedList
  250. //
  251. public virtual IList GetKeyList ()
  252. {
  253. return new ListKeys (this);
  254. }
  255. public virtual IList GetValueList ()
  256. {
  257. return new ListValues (this);
  258. }
  259. public virtual void RemoveAt (int index)
  260. {
  261. Slot [] table = this.table;
  262. int cnt = Count;
  263. if (index >= 0 && index < cnt) {
  264. if (index != cnt - 1) {
  265. Array.Copy (table, index+1, table, index, cnt-1-index);
  266. } else {
  267. table [index].key = null;
  268. table [index].value = null;
  269. }
  270. --inUse;
  271. ++modificationCount;
  272. } else {
  273. throw new ArgumentOutOfRangeException("index out of range");
  274. }
  275. }
  276. public virtual int IndexOfKey (object key)
  277. {
  278. if (null == key)
  279. throw new ArgumentNullException();
  280. int indx = 0;
  281. try {
  282. indx = Find (key);
  283. } catch (Exception) {
  284. throw new InvalidOperationException();
  285. }
  286. return (indx | (indx >> 31));
  287. }
  288. public virtual int IndexOfValue (object value)
  289. {
  290. if (inUse == 0)
  291. return -1;
  292. for (int i = 0; i < inUse; i ++) {
  293. Slot current = this.table [i];
  294. if (Equals (value, current.value))
  295. return i;
  296. }
  297. return -1;
  298. }
  299. public virtual bool ContainsKey (object key)
  300. {
  301. if (null == key)
  302. throw new ArgumentNullException();
  303. try {
  304. return Contains (key);
  305. } catch (Exception) {
  306. throw new InvalidOperationException();
  307. }
  308. }
  309. public virtual bool ContainsValue (object value)
  310. {
  311. return IndexOfValue (value) >= 0;
  312. }
  313. public virtual object GetByIndex (int index)
  314. {
  315. if (index >= 0 && index < Count)
  316. return table [index].value;
  317. else
  318. throw new ArgumentOutOfRangeException("index out of range");
  319. }
  320. public virtual void SetByIndex (int index, object value)
  321. {
  322. if (index >= 0 && index < Count)
  323. table [index].value = value;
  324. else
  325. throw new ArgumentOutOfRangeException("index out of range");
  326. }
  327. public virtual object GetKey (int index)
  328. {
  329. if (index >= 0 && index < Count)
  330. return table [index].key;
  331. else
  332. throw new ArgumentOutOfRangeException("index out of range");
  333. }
  334. public static SortedList Synchronized (SortedList list)
  335. {
  336. if (list == null)
  337. throw new ArgumentNullException (Locale.GetText ("Base list is null."));
  338. return new SynchedSortedList (list);
  339. }
  340. public virtual void TrimToSize ()
  341. {
  342. // From Beta2:
  343. // Trimming an empty SortedList sets the capacity
  344. // of the SortedList to the default capacity,
  345. // not zero.
  346. if (Count == 0)
  347. Resize (defaultCapacity, false);
  348. else
  349. Resize (Count, true);
  350. }
  351. //
  352. // Private methods
  353. //
  354. private void Resize (int n, bool copy)
  355. {
  356. Slot [] table = this.table;
  357. Slot [] newTable = new Slot [n];
  358. if (copy) Array.Copy (table, 0, newTable, 0, n);
  359. this.table = newTable;
  360. }
  361. private void EnsureCapacity (int n, int free)
  362. {
  363. Slot [] table = this.table;
  364. Slot [] newTable = null;
  365. int cap = Capacity;
  366. bool gap = (free >=0 && free < Count);
  367. if (n > cap) {
  368. newTable = new Slot [n << 1];
  369. }
  370. if (newTable != null) {
  371. if (gap) {
  372. int copyLen = free;
  373. if (copyLen > 0) {
  374. Array.Copy (table, 0, newTable, 0, copyLen);
  375. }
  376. copyLen = Count - free;
  377. if (copyLen > 0) {
  378. Array.Copy (table, free, newTable, free+1, copyLen);
  379. }
  380. } else {
  381. // Just a resizing, copy the entire table.
  382. Array.Copy (table, newTable, Count);
  383. }
  384. this.table = newTable;
  385. } else if (gap) {
  386. Array.Copy (table, free, table, free+1, Count - free);
  387. }
  388. }
  389. private void PutImpl (object key, object value, bool overwrite)
  390. {
  391. if (key == null)
  392. throw new ArgumentNullException ("null key");
  393. Slot [] table = this.table;
  394. int freeIndx = -1;
  395. try {
  396. freeIndx = Find (key);
  397. } catch (Exception) {
  398. throw new InvalidOperationException();
  399. }
  400. if (freeIndx >= 0) {
  401. if (!overwrite) {
  402. string msg = Locale.GetText ("Key '{0}' already exists in list.", key);
  403. throw new ArgumentException (msg);
  404. }
  405. table [freeIndx].value = value;
  406. ++modificationCount;
  407. return;
  408. }
  409. freeIndx = ~freeIndx;
  410. if (freeIndx > Capacity + 1)
  411. throw new Exception ("SortedList::internal error ("+key+", "+value+") at ["+freeIndx+"]");
  412. EnsureCapacity (Count+1, freeIndx);
  413. table = this.table;
  414. table [freeIndx].key = key;
  415. table [freeIndx].value = value;
  416. ++inUse;
  417. ++modificationCount;
  418. }
  419. private object GetImpl (object key)
  420. {
  421. int i = Find (key);
  422. if (i >= 0)
  423. return table [i].value;
  424. else
  425. return null;
  426. }
  427. private void InitTable (int capacity, bool forceSize)
  428. {
  429. if (!forceSize && (capacity < defaultCapacity))
  430. capacity = defaultCapacity;
  431. this.table = new Slot [capacity];
  432. this.inUse = 0;
  433. this.modificationCount = 0;
  434. }
  435. private void CopyToArray (Array arr, int i,
  436. EnumeratorMode mode)
  437. {
  438. if (arr == null)
  439. throw new ArgumentNullException ("arr");
  440. if (i < 0 || i + this.Count > arr.Length)
  441. throw new ArgumentOutOfRangeException ("i");
  442. IEnumerator it = new Enumerator (this, mode);
  443. while (it.MoveNext ()) {
  444. arr.SetValue (it.Current, i++);
  445. }
  446. }
  447. private int Find (object key)
  448. {
  449. Slot [] table = this.table;
  450. int len = Count;
  451. if (len == 0) return ~0;
  452. IComparer comparer = (this.comparer == null)
  453. ? Comparer.Default
  454. : this.comparer;
  455. int left = 0;
  456. int right = len-1;
  457. while (left <= right) {
  458. int guess = (int)((uint)(left + right) >> 1);
  459. int cmp = comparer.Compare (table[guess].key, key);
  460. if (cmp == 0) return guess;
  461. if (cmp < 0) left = guess+1;
  462. else right = guess-1;
  463. }
  464. return ~left;
  465. }
  466. //
  467. // Inner classes
  468. //
  469. private sealed class Enumerator : ICloneable, IDictionaryEnumerator, IEnumerator {
  470. private SortedList host;
  471. private object currentKey;
  472. private object currentValue;
  473. private int stamp;
  474. private int pos;
  475. private int size;
  476. private EnumeratorMode mode;
  477. bool invalid;
  478. const string xstr = "SortedList.Enumerator: snapshot out of sync.";
  479. public Enumerator (SortedList host, EnumeratorMode mode)
  480. {
  481. this.host = host;
  482. stamp = host.modificationCount;
  483. size = host.Count;
  484. this.mode = mode;
  485. Reset ();
  486. }
  487. public Enumerator (SortedList host)
  488. : this (host, EnumeratorMode.ENTRY_MODE)
  489. {
  490. }
  491. public void Reset ()
  492. {
  493. if (host.modificationCount != stamp || invalid)
  494. throw new InvalidOperationException (xstr);
  495. pos = -1;
  496. currentKey = null;
  497. currentValue = null;
  498. }
  499. public bool MoveNext ()
  500. {
  501. if (host.modificationCount != stamp || invalid)
  502. throw new InvalidOperationException (xstr);
  503. Slot [] table = host.table;
  504. if (++pos < size) {
  505. Slot entry = table [pos];
  506. currentKey = entry.key;
  507. currentValue = entry.value;
  508. return true;
  509. }
  510. currentKey = null;
  511. currentValue = null;
  512. return false;
  513. }
  514. public DictionaryEntry Entry
  515. {
  516. get {
  517. if (invalid || pos >= size || pos == -1)
  518. throw new InvalidOperationException (xstr);
  519. return new DictionaryEntry (currentKey,
  520. currentValue);
  521. }
  522. }
  523. public Object Key {
  524. get {
  525. if (invalid || pos >= size || pos == -1)
  526. throw new InvalidOperationException (xstr);
  527. return currentKey;
  528. }
  529. }
  530. public Object Value {
  531. get {
  532. if (invalid || pos >= size || pos == -1)
  533. throw new InvalidOperationException (xstr);
  534. return currentValue;
  535. }
  536. }
  537. public Object Current {
  538. get {
  539. if (invalid || pos >= size || pos == -1)
  540. throw new InvalidOperationException (xstr);
  541. switch (mode) {
  542. case EnumeratorMode.KEY_MODE:
  543. return currentKey;
  544. case EnumeratorMode.VALUE_MODE:
  545. return currentValue;
  546. case EnumeratorMode.ENTRY_MODE:
  547. return this.Entry;
  548. default:
  549. throw new NotSupportedException (mode + " is not a supported mode.");
  550. }
  551. }
  552. }
  553. // ICloneable
  554. public object Clone ()
  555. {
  556. Enumerator e = new Enumerator (host, mode);
  557. e.stamp = stamp;
  558. e.pos = pos;
  559. e.size = size;
  560. e.currentKey = currentKey;
  561. e.currentValue = currentValue;
  562. e.invalid = invalid;
  563. return e;
  564. }
  565. }
  566. [Serializable]
  567. private class ListKeys : IList, IEnumerable {
  568. private SortedList host;
  569. public ListKeys (SortedList host)
  570. {
  571. if (host == null)
  572. throw new ArgumentNullException ();
  573. this.host = host;
  574. }
  575. //
  576. // ICollection
  577. //
  578. public virtual int Count {
  579. get {
  580. return host.Count;
  581. }
  582. }
  583. public virtual bool IsSynchronized {
  584. get {
  585. return host.IsSynchronized;
  586. }
  587. }
  588. public virtual Object SyncRoot {
  589. get {
  590. return host.SyncRoot;
  591. }
  592. }
  593. public virtual void CopyTo (Array array, int arrayIndex)
  594. {
  595. host.CopyToArray (array, arrayIndex, EnumeratorMode.KEY_MODE);
  596. }
  597. //
  598. // IList
  599. //
  600. public virtual bool IsFixedSize {
  601. get {
  602. return true;
  603. }
  604. }
  605. public virtual bool IsReadOnly {
  606. get {
  607. return true;
  608. }
  609. }
  610. public virtual object this [int index] {
  611. get {
  612. return host.GetKey (index);
  613. }
  614. set {
  615. throw new NotSupportedException("attempt to modify a key");
  616. }
  617. }
  618. public virtual int Add (object value)
  619. {
  620. throw new NotSupportedException("IList::Add not supported");
  621. }
  622. public virtual void Clear ()
  623. {
  624. throw new NotSupportedException("IList::Clear not supported");
  625. }
  626. public virtual bool Contains (object key)
  627. {
  628. return host.Contains (key);
  629. }
  630. public virtual int IndexOf (object key)
  631. {
  632. return host.IndexOfKey (key);
  633. }
  634. public virtual void Insert (int index, object value)
  635. {
  636. throw new NotSupportedException("IList::Insert not supported");
  637. }
  638. public virtual void Remove (object value)
  639. {
  640. throw new NotSupportedException("IList::Remove not supported");
  641. }
  642. public virtual void RemoveAt (int index)
  643. {
  644. throw new NotSupportedException("IList::RemoveAt not supported");
  645. }
  646. //
  647. // IEnumerable
  648. //
  649. public virtual IEnumerator GetEnumerator ()
  650. {
  651. return new SortedList.Enumerator (host, EnumeratorMode.KEY_MODE);
  652. }
  653. }
  654. [Serializable]
  655. private class ListValues : IList, IEnumerable {
  656. private SortedList host;
  657. public ListValues (SortedList host)
  658. {
  659. if (host == null)
  660. throw new ArgumentNullException ();
  661. this.host = host;
  662. }
  663. //
  664. // ICollection
  665. //
  666. public virtual int Count {
  667. get {
  668. return host.Count;
  669. }
  670. }
  671. public virtual bool IsSynchronized {
  672. get {
  673. return host.IsSynchronized;
  674. }
  675. }
  676. public virtual Object SyncRoot {
  677. get {
  678. return host.SyncRoot;
  679. }
  680. }
  681. public virtual void CopyTo (Array array, int arrayIndex)
  682. {
  683. host.CopyToArray (array, arrayIndex, EnumeratorMode.VALUE_MODE);
  684. }
  685. //
  686. // IList
  687. //
  688. public virtual bool IsFixedSize {
  689. get {
  690. return true;
  691. }
  692. }
  693. public virtual bool IsReadOnly {
  694. get {
  695. return true;
  696. }
  697. }
  698. public virtual object this [int index] {
  699. get {
  700. return host.GetByIndex (index);
  701. }
  702. set {
  703. throw new NotSupportedException("This operation is not supported on GetValueList return");
  704. }
  705. }
  706. public virtual int Add (object value)
  707. {
  708. throw new NotSupportedException("IList::Add not supported");
  709. }
  710. public virtual void Clear ()
  711. {
  712. throw new NotSupportedException("IList::Clear not supported");
  713. }
  714. public virtual bool Contains (object value)
  715. {
  716. return host.ContainsValue (value);
  717. }
  718. public virtual int IndexOf (object value)
  719. {
  720. return host.IndexOfValue (value);
  721. }
  722. public virtual void Insert (int index, object value)
  723. {
  724. throw new NotSupportedException("IList::Insert not supported");
  725. }
  726. public virtual void Remove (object value)
  727. {
  728. throw new NotSupportedException("IList::Remove not supported");
  729. }
  730. public virtual void RemoveAt (int index)
  731. {
  732. throw new NotSupportedException("IList::RemoveAt not supported");
  733. }
  734. //
  735. // IEnumerable
  736. //
  737. public virtual IEnumerator GetEnumerator ()
  738. {
  739. return new SortedList.Enumerator (host, EnumeratorMode.VALUE_MODE);
  740. }
  741. }
  742. private class SynchedSortedList : SortedList {
  743. private SortedList host;
  744. public SynchedSortedList (SortedList host)
  745. {
  746. if (host == null)
  747. throw new ArgumentNullException ();
  748. this.host = host;
  749. }
  750. public override int Capacity {
  751. get {
  752. lock (host.SyncRoot) {
  753. return host.Capacity;
  754. }
  755. }
  756. set {
  757. lock (host.SyncRoot) {
  758. host.Capacity = value;
  759. }
  760. }
  761. }
  762. // ICollection
  763. public override int Count {
  764. get {
  765. return host.Count;
  766. }
  767. }
  768. public override bool IsSynchronized {
  769. get {
  770. return true;
  771. }
  772. }
  773. public override Object SyncRoot {
  774. get {
  775. return host.SyncRoot;
  776. }
  777. }
  778. // IDictionary
  779. public override bool IsFixedSize {
  780. get {
  781. return host.IsFixedSize;
  782. }
  783. }
  784. public override bool IsReadOnly {
  785. get {
  786. return host.IsReadOnly;
  787. }
  788. }
  789. public override ICollection Keys {
  790. get {
  791. ICollection keys = null;
  792. lock (host.SyncRoot) {
  793. keys = host.Keys;
  794. }
  795. return keys;
  796. }
  797. }
  798. public override ICollection Values {
  799. get {
  800. ICollection vals = null;
  801. lock (host.SyncRoot) {
  802. vals = host.Values;
  803. }
  804. return vals;
  805. }
  806. }
  807. public override Object this [object key] {
  808. get {
  809. lock (host.SyncRoot) {
  810. return host.GetImpl (key);
  811. }
  812. }
  813. set {
  814. lock (host.SyncRoot) {
  815. host.PutImpl (key, value, true);
  816. }
  817. }
  818. }
  819. // ICollection
  820. public override void CopyTo (Array array, int arrayIndex)
  821. {
  822. lock (host.SyncRoot) {
  823. host.CopyTo (array, arrayIndex);
  824. }
  825. }
  826. // IDictionary
  827. public override void Add (object key, object value)
  828. {
  829. lock (host.SyncRoot) {
  830. host.PutImpl (key, value, false);
  831. }
  832. }
  833. public override void Clear ()
  834. {
  835. lock (host.SyncRoot) {
  836. host.Clear ();
  837. }
  838. }
  839. public override bool Contains (object key)
  840. {
  841. lock (host.SyncRoot) {
  842. return (host.Find (key) >= 0);
  843. }
  844. }
  845. public override IDictionaryEnumerator GetEnumerator ()
  846. {
  847. lock (host.SyncRoot) {
  848. return host.GetEnumerator();
  849. }
  850. }
  851. public override void Remove (object key)
  852. {
  853. lock (host.SyncRoot) {
  854. host.Remove (key);
  855. }
  856. }
  857. public override bool ContainsKey (object key)
  858. {
  859. lock (host.SyncRoot) {
  860. return host.Contains (key);
  861. }
  862. }
  863. public override bool ContainsValue (object value)
  864. {
  865. lock (host.SyncRoot) {
  866. return host.ContainsValue (value);
  867. }
  868. }
  869. // ICloneable
  870. public override object Clone ()
  871. {
  872. lock (host.SyncRoot) {
  873. return (host.Clone () as SortedList);
  874. }
  875. }
  876. //
  877. // SortedList overrides
  878. //
  879. public override Object GetByIndex (int index)
  880. {
  881. lock (host.SyncRoot) {
  882. return host.GetByIndex (index);
  883. }
  884. }
  885. public override Object GetKey (int index)
  886. {
  887. lock (host.SyncRoot) {
  888. return host.GetKey (index);
  889. }
  890. }
  891. public override IList GetKeyList ()
  892. {
  893. lock (host.SyncRoot) {
  894. return new ListKeys (host);
  895. }
  896. }
  897. public override IList GetValueList ()
  898. {
  899. lock (host.SyncRoot) {
  900. return new ListValues (host);
  901. }
  902. }
  903. public override void RemoveAt (int index)
  904. {
  905. lock (host.SyncRoot) {
  906. host.RemoveAt (index);
  907. }
  908. }
  909. public override int IndexOfKey (object key)
  910. {
  911. lock (host.SyncRoot) {
  912. return host.IndexOfKey (key);
  913. }
  914. }
  915. public override int IndexOfValue (Object val)
  916. {
  917. lock (host.SyncRoot) {
  918. return host.IndexOfValue (val);
  919. }
  920. }
  921. public override void SetByIndex (int index, object value)
  922. {
  923. lock (host.SyncRoot) {
  924. host.SetByIndex (index, value);
  925. }
  926. }
  927. public override void TrimToSize()
  928. {
  929. lock (host.SyncRoot) {
  930. host.TrimToSize();
  931. }
  932. }
  933. } // SynchedSortedList
  934. } // SortedList
  935. } // System.Collections