BsonArray.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  1. /* Copyright 2010-present MongoDB Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. using System;
  16. using System.Collections;
  17. using System.Collections.Generic;
  18. using System.Linq;
  19. using System.Text;
  20. using MongoDB.Shared;
  21. namespace MongoDB.Bson
  22. {
  23. /// <summary>
  24. /// Represents a BSON array.
  25. /// </summary>
  26. [Serializable]
  27. public class BsonArray : BsonValue, IComparable<BsonArray>, IEquatable<BsonArray>, IList<BsonValue>
  28. {
  29. // private fields
  30. private readonly List<BsonValue> _values;
  31. // constructors
  32. /// <summary>
  33. /// Initializes a new instance of the BsonArray class.
  34. /// </summary>
  35. public BsonArray()
  36. : this(0)
  37. {
  38. }
  39. /// <summary>
  40. /// Initializes a new instance of the BsonArray class.
  41. /// </summary>
  42. /// <param name="values">A list of values to add to the array.</param>
  43. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
  44. public BsonArray(IEnumerable<bool> values)
  45. : this(0)
  46. {
  47. AddRange(values);
  48. }
  49. /// <summary>
  50. /// Initializes a new instance of the BsonArray class.
  51. /// </summary>
  52. /// <param name="values">A list of values to add to the array.</param>
  53. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
  54. public BsonArray(IEnumerable<BsonValue> values)
  55. : this(0)
  56. {
  57. AddRange(values);
  58. }
  59. /// <summary>
  60. /// Initializes a new instance of the BsonArray class.
  61. /// </summary>
  62. /// <param name="values">A list of values to add to the array.</param>
  63. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
  64. public BsonArray(IEnumerable<DateTime> values)
  65. : this(0)
  66. {
  67. AddRange(values);
  68. }
  69. /// <summary>
  70. /// Initializes a new instance of the BsonArray class.
  71. /// </summary>
  72. /// <param name="values">A list of values to add to the array.</param>
  73. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
  74. public BsonArray(IEnumerable<double> values)
  75. : this(0)
  76. {
  77. AddRange(values);
  78. }
  79. /// <summary>
  80. /// Initializes a new instance of the BsonArray class.
  81. /// </summary>
  82. /// <param name="values">A list of values to add to the array.</param>
  83. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
  84. public BsonArray(IEnumerable<int> values)
  85. : this(0)
  86. {
  87. AddRange(values);
  88. }
  89. /// <summary>
  90. /// Initializes a new instance of the BsonArray class.
  91. /// </summary>
  92. /// <param name="values">A list of values to add to the array.</param>
  93. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
  94. public BsonArray(IEnumerable<long> values)
  95. : this(0)
  96. {
  97. AddRange(values);
  98. }
  99. /// <summary>
  100. /// Initializes a new instance of the BsonArray class.
  101. /// </summary>
  102. /// <param name="values">A list of values to add to the array.</param>
  103. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
  104. public BsonArray(IEnumerable<ObjectId> values)
  105. : this(0)
  106. {
  107. AddRange(values);
  108. }
  109. /// <summary>
  110. /// Initializes a new instance of the BsonArray class.
  111. /// </summary>
  112. /// <param name="values">A list of values to add to the array.</param>
  113. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
  114. public BsonArray(IEnumerable<string> values)
  115. : this(0)
  116. {
  117. AddRange(values);
  118. }
  119. /// <summary>
  120. /// Initializes a new instance of the BsonArray class.
  121. /// </summary>
  122. /// <param name="values">A list of values to add to the array.</param>
  123. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
  124. public BsonArray(IEnumerable values)
  125. : this(0)
  126. {
  127. AddRange(values);
  128. }
  129. /// <summary>
  130. /// Initializes a new instance of the BsonArray class.
  131. /// </summary>
  132. /// <param name="capacity">The initial capacity of the array.</param>
  133. public BsonArray(int capacity)
  134. {
  135. _values = new List<BsonValue>(capacity);
  136. }
  137. // public operators
  138. /// <summary>
  139. /// Compares two BsonArray values.
  140. /// </summary>
  141. /// <param name="lhs">The first BsonArray.</param>
  142. /// <param name="rhs">The other BsonArray.</param>
  143. /// <returns>True if the two BsonArray values are not equal according to ==.</returns>
  144. public static bool operator !=(BsonArray lhs, BsonArray rhs)
  145. {
  146. return !(lhs == rhs);
  147. }
  148. /// <summary>
  149. /// Compares two BsonArray values.
  150. /// </summary>
  151. /// <param name="lhs">The first BsonArray.</param>
  152. /// <param name="rhs">The other BsonArray.</param>
  153. /// <returns>True if the two BsonArray values are equal according to ==.</returns>
  154. public static bool operator ==(BsonArray lhs, BsonArray rhs)
  155. {
  156. return object.Equals(lhs, rhs); // handles lhs == null correctly
  157. }
  158. // public properties
  159. /// <summary>
  160. /// Gets the BsonType of this BsonValue.
  161. /// </summary>
  162. public override BsonType BsonType
  163. {
  164. get { return BsonType.Array; }
  165. }
  166. /// <summary>
  167. /// Gets or sets the total number of elements the internal data structure can hold without resizing.
  168. /// </summary>
  169. public virtual int Capacity
  170. {
  171. get { return _values.Capacity; }
  172. set { _values.Capacity = value; }
  173. }
  174. /// <summary>
  175. /// Gets the count of array elements.
  176. /// </summary>
  177. public virtual int Count
  178. {
  179. get { return _values.Count; }
  180. }
  181. /// <summary>
  182. /// Gets whether the array is read-only.
  183. /// </summary>
  184. public virtual bool IsReadOnly
  185. {
  186. get { return false; }
  187. }
  188. /// <summary>
  189. /// Gets the array elements as raw values (see BsonValue.RawValue).
  190. /// </summary>
  191. [Obsolete("Use ToArray to ToList instead.")]
  192. public virtual IEnumerable<object> RawValues
  193. {
  194. get { return _values.Select(v => v.RawValue); }
  195. }
  196. /// <summary>
  197. /// Gets the array elements.
  198. /// </summary>
  199. public virtual IEnumerable<BsonValue> Values
  200. {
  201. get { return _values; }
  202. }
  203. // public indexers
  204. /// <summary>
  205. /// Gets or sets a value by position.
  206. /// </summary>
  207. /// <param name="index">The position.</param>
  208. /// <returns>The value.</returns>
  209. public override BsonValue this[int index]
  210. {
  211. get { return _values[index]; }
  212. set
  213. {
  214. if (value == null)
  215. {
  216. throw new ArgumentNullException("value");
  217. }
  218. _values[index] = value;
  219. }
  220. }
  221. // public static methods
  222. /// <summary>
  223. /// Creates a new BsonArray.
  224. /// </summary>
  225. /// <param name="value">A value to be mapped to a BsonArray.</param>
  226. /// <returns>A BsonArray or null.</returns>
  227. public new static BsonArray Create(object value)
  228. {
  229. if (value == null)
  230. {
  231. throw new ArgumentNullException("value");
  232. }
  233. return (BsonArray)BsonTypeMapper.MapToBsonValue(value, BsonType.Array);
  234. }
  235. // public methods
  236. /// <summary>
  237. /// Adds an element to the array.
  238. /// </summary>
  239. /// <param name="value">The value to add to the array.</param>
  240. /// <returns>The array (so method calls can be chained).</returns>
  241. public virtual BsonArray Add(BsonValue value)
  242. {
  243. if (value == null)
  244. {
  245. throw new ArgumentNullException("value");
  246. }
  247. _values.Add(value);
  248. return this;
  249. }
  250. /// <summary>
  251. /// Adds multiple elements to the array.
  252. /// </summary>
  253. /// <param name="values">A list of values to add to the array.</param>
  254. /// <returns>The array (so method calls can be chained).</returns>
  255. public virtual BsonArray AddRange(IEnumerable<bool> values)
  256. {
  257. if (values == null)
  258. {
  259. throw new ArgumentNullException("values");
  260. }
  261. foreach (var value in values)
  262. {
  263. Add((BsonBoolean)value);
  264. }
  265. return this;
  266. }
  267. /// <summary>
  268. /// Adds multiple elements to the array.
  269. /// </summary>
  270. /// <param name="values">A list of values to add to the array.</param>
  271. /// <returns>The array (so method calls can be chained).</returns>
  272. public virtual BsonArray AddRange(IEnumerable<BsonValue> values)
  273. {
  274. if (values == null)
  275. {
  276. throw new ArgumentNullException("values");
  277. }
  278. foreach (var value in values)
  279. {
  280. Add(value);
  281. }
  282. return this;
  283. }
  284. /// <summary>
  285. /// Adds multiple elements to the array.
  286. /// </summary>
  287. /// <param name="values">A list of values to add to the array.</param>
  288. /// <returns>The array (so method calls can be chained).</returns>
  289. public virtual BsonArray AddRange(IEnumerable<DateTime> values)
  290. {
  291. if (values == null)
  292. {
  293. throw new ArgumentNullException("values");
  294. }
  295. foreach (var value in values)
  296. {
  297. Add(new BsonDateTime(value));
  298. }
  299. return this;
  300. }
  301. /// <summary>
  302. /// Adds multiple elements to the array.
  303. /// </summary>
  304. /// <param name="values">A list of values to add to the array.</param>
  305. /// <returns>The array (so method calls can be chained).</returns>
  306. public virtual BsonArray AddRange(IEnumerable<double> values)
  307. {
  308. if (values == null)
  309. {
  310. throw new ArgumentNullException("values");
  311. }
  312. foreach (var value in values)
  313. {
  314. Add((BsonDouble)value);
  315. }
  316. return this;
  317. }
  318. /// <summary>
  319. /// Adds multiple elements to the array.
  320. /// </summary>
  321. /// <param name="values">A list of values to add to the array.</param>
  322. /// <returns>The array (so method calls can be chained).</returns>
  323. public virtual BsonArray AddRange(IEnumerable<int> values)
  324. {
  325. if (values == null)
  326. {
  327. throw new ArgumentNullException("values");
  328. }
  329. foreach (var value in values)
  330. {
  331. Add((BsonInt32)value);
  332. }
  333. return this;
  334. }
  335. /// <summary>
  336. /// Adds multiple elements to the array.
  337. /// </summary>
  338. /// <param name="values">A list of values to add to the array.</param>
  339. /// <returns>The array (so method calls can be chained).</returns>
  340. public virtual BsonArray AddRange(IEnumerable<long> values)
  341. {
  342. if (values == null)
  343. {
  344. throw new ArgumentNullException("values");
  345. }
  346. foreach (var value in values)
  347. {
  348. Add((BsonInt64)value);
  349. }
  350. return this;
  351. }
  352. /// <summary>
  353. /// Adds multiple elements to the array.
  354. /// </summary>
  355. /// <param name="values">A list of values to add to the array.</param>
  356. /// <returns>The array (so method calls can be chained).</returns>
  357. public virtual BsonArray AddRange(IEnumerable<ObjectId> values)
  358. {
  359. if (values == null)
  360. {
  361. throw new ArgumentNullException("values");
  362. }
  363. foreach (var value in values)
  364. {
  365. Add(new BsonObjectId(value));
  366. }
  367. return this;
  368. }
  369. /// <summary>
  370. /// Adds multiple elements to the array.
  371. /// </summary>
  372. /// <param name="values">A list of values to add to the array.</param>
  373. /// <returns>The array (so method calls can be chained).</returns>
  374. public virtual BsonArray AddRange(IEnumerable<string> values)
  375. {
  376. if (values == null)
  377. {
  378. throw new ArgumentNullException("values");
  379. }
  380. foreach (var value in values)
  381. {
  382. _values.Add((value == null) ? (BsonValue)BsonNull.Value : (BsonString)value);
  383. }
  384. return this;
  385. }
  386. /// <summary>
  387. /// Adds multiple elements to the array.
  388. /// </summary>
  389. /// <param name="values">A list of values to add to the array.</param>
  390. /// <returns>The array (so method calls can be chained).</returns>
  391. public virtual BsonArray AddRange(IEnumerable values)
  392. {
  393. if (values == null)
  394. {
  395. throw new ArgumentNullException("values");
  396. }
  397. foreach (var value in values)
  398. {
  399. Add(BsonTypeMapper.MapToBsonValue(value));
  400. }
  401. return this;
  402. }
  403. /// <summary>
  404. /// Creates a shallow clone of the array (see also DeepClone).
  405. /// </summary>
  406. /// <returns>A shallow clone of the array.</returns>
  407. public override BsonValue Clone()
  408. {
  409. var clone = new BsonArray(_values.Capacity);
  410. foreach (var value in _values)
  411. {
  412. clone.Add(value);
  413. }
  414. return clone;
  415. }
  416. /// <summary>
  417. /// Clears the array.
  418. /// </summary>
  419. public virtual void Clear()
  420. {
  421. _values.Clear();
  422. }
  423. /// <summary>
  424. /// Compares the array to another array.
  425. /// </summary>
  426. /// <param name="rhs">The other array.</param>
  427. /// <returns>A 32-bit signed integer that indicates whether this array is less than, equal to, or greather than the other.</returns>
  428. public virtual int CompareTo(BsonArray rhs)
  429. {
  430. if (rhs == null) { return 1; }
  431. // lhs and rhs might be subclasses of BsonArray
  432. using (var lhsEnumerator = GetEnumerator())
  433. using (var rhsEnumerator = rhs.GetEnumerator())
  434. {
  435. while (true)
  436. {
  437. var lhsHasNext = lhsEnumerator.MoveNext();
  438. var rhsHasNext = rhsEnumerator.MoveNext();
  439. if (!lhsHasNext && !rhsHasNext) { return 0; }
  440. if (!lhsHasNext) { return -1; }
  441. if (!rhsHasNext) { return 1; }
  442. var lhsValue = lhsEnumerator.Current;
  443. var rhsValue = rhsEnumerator.Current;
  444. var result = lhsValue.CompareTo(rhsValue);
  445. if (result != 0) { return result; }
  446. }
  447. }
  448. }
  449. /// <summary>
  450. /// Compares the array to another BsonValue.
  451. /// </summary>
  452. /// <param name="other">The other BsonValue.</param>
  453. /// <returns>A 32-bit signed integer that indicates whether this array is less than, equal to, or greather than the other BsonValue.</returns>
  454. public override int CompareTo(BsonValue other)
  455. {
  456. if (other == null) { return 1; }
  457. var otherArray = other as BsonArray;
  458. if (otherArray != null)
  459. {
  460. return CompareTo(otherArray);
  461. }
  462. return CompareTypeTo(other);
  463. }
  464. /// <summary>
  465. /// Tests whether the array contains a value.
  466. /// </summary>
  467. /// <param name="value">The value to test for.</param>
  468. /// <returns>True if the array contains the value.</returns>
  469. public virtual bool Contains(BsonValue value)
  470. {
  471. // don't throw ArgumentNullException if value is null
  472. // just let _values.Contains return false
  473. return _values.Contains(value);
  474. }
  475. /// <summary>
  476. /// Copies elements from this array to another array.
  477. /// </summary>
  478. /// <param name="array">The other array.</param>
  479. /// <param name="arrayIndex">The zero based index of the other array at which to start copying.</param>
  480. public virtual void CopyTo(BsonValue[] array, int arrayIndex)
  481. {
  482. for (int i = 0, j = arrayIndex; i < _values.Count; i++, j++)
  483. {
  484. array[j] = _values[i];
  485. }
  486. }
  487. /// <summary>
  488. /// Copies elements from this array to another array as raw values (see BsonValue.RawValue).
  489. /// </summary>
  490. /// <param name="array">The other array.</param>
  491. /// <param name="arrayIndex">The zero based index of the other array at which to start copying.</param>
  492. [Obsolete("Use ToArray or ToList instead.")]
  493. public virtual void CopyTo(object[] array, int arrayIndex)
  494. {
  495. for (int i = 0, j = arrayIndex; i < _values.Count; i++, j++)
  496. {
  497. array[j] = _values[i].RawValue;
  498. }
  499. }
  500. /// <summary>
  501. /// Creates a deep clone of the array (see also Clone).
  502. /// </summary>
  503. /// <returns>A deep clone of the array.</returns>
  504. public override BsonValue DeepClone()
  505. {
  506. var clone = new BsonArray(_values.Capacity);
  507. foreach (var value in _values)
  508. {
  509. clone.Add(value.DeepClone());
  510. }
  511. return clone;
  512. }
  513. /// <summary>
  514. /// Compares this array to another array.
  515. /// </summary>
  516. /// <param name="obj">The other array.</param>
  517. /// <returns>True if the two arrays are equal.</returns>
  518. public bool Equals(BsonArray obj)
  519. {
  520. return Equals((object)obj); // handles obj == null correctly
  521. }
  522. /// <summary>
  523. /// Compares this BsonArray to another object.
  524. /// </summary>
  525. /// <param name="obj">The other object.</param>
  526. /// <returns>True if the other object is a BsonArray and equal to this one.</returns>
  527. public override bool Equals(object obj)
  528. {
  529. if (object.ReferenceEquals(obj, null) || !(obj is BsonArray)) { return false; }
  530. // lhs and rhs might be subclasses of BsonArray
  531. var rhs = (BsonArray)obj;
  532. return Values.SequenceEqual(rhs.Values);
  533. }
  534. /// <summary>
  535. /// Gets an enumerator that can enumerate the elements of the array.
  536. /// </summary>
  537. /// <returns>An enumerator.</returns>
  538. public virtual IEnumerator<BsonValue> GetEnumerator()
  539. {
  540. return _values.GetEnumerator();
  541. }
  542. /// <summary>
  543. /// Gets the hash code.
  544. /// </summary>
  545. /// <returns>The hash code.</returns>
  546. public override int GetHashCode()
  547. {
  548. return new Hasher()
  549. .Hash(BsonType)
  550. .HashElements(Values)
  551. .GetHashCode();
  552. }
  553. /// <summary>
  554. /// Gets the index of a value in the array.
  555. /// </summary>
  556. /// <param name="value">The value to search for.</param>
  557. /// <returns>The zero based index of the value (or -1 if not found).</returns>
  558. public virtual int IndexOf(BsonValue value)
  559. {
  560. if (value == null)
  561. {
  562. throw new ArgumentNullException("value");
  563. }
  564. return _values.IndexOf(value);
  565. }
  566. /// <summary>
  567. /// Gets the index of a value in the array.
  568. /// </summary>
  569. /// <param name="value">The value to search for.</param>
  570. /// <param name="index">The zero based index at which to start the search.</param>
  571. /// <returns>The zero based index of the value (or -1 if not found).</returns>
  572. public virtual int IndexOf(BsonValue value, int index)
  573. {
  574. if (value == null)
  575. {
  576. throw new ArgumentNullException("value");
  577. }
  578. return _values.IndexOf(value, index);
  579. }
  580. /// <summary>
  581. /// Gets the index of a value in the array.
  582. /// </summary>
  583. /// <param name="value">The value to search for.</param>
  584. /// <param name="index">The zero based index at which to start the search.</param>
  585. /// <param name="count">The number of elements to search.</param>
  586. /// <returns>The zero based index of the value (or -1 if not found).</returns>
  587. public virtual int IndexOf(BsonValue value, int index, int count)
  588. {
  589. if (value == null)
  590. {
  591. throw new ArgumentNullException("value");
  592. }
  593. return _values.IndexOf(value, index, count);
  594. }
  595. /// <summary>
  596. /// Inserts a new value into the array.
  597. /// </summary>
  598. /// <param name="index">The zero based index at which to insert the new value.</param>
  599. /// <param name="value">The new value.</param>
  600. public virtual void Insert(int index, BsonValue value)
  601. {
  602. if (value == null)
  603. {
  604. throw new ArgumentNullException("value");
  605. }
  606. _values.Insert(index, value);
  607. }
  608. /// <summary>
  609. /// Removes the first occurrence of a value from the array.
  610. /// </summary>
  611. /// <param name="value">The value to remove.</param>
  612. /// <returns>True if the value was removed.</returns>
  613. public virtual bool Remove(BsonValue value)
  614. {
  615. if (value == null)
  616. {
  617. throw new ArgumentNullException("value");
  618. }
  619. return _values.Remove(value);
  620. }
  621. /// <summary>
  622. /// Removes an element from the array.
  623. /// </summary>
  624. /// <param name="index">The zero based index of the element to remove.</param>
  625. public virtual void RemoveAt(int index)
  626. {
  627. _values.RemoveAt(index);
  628. }
  629. /// <summary>
  630. /// Converts the BsonArray to an array of BsonValues.
  631. /// </summary>
  632. /// <returns>An array of BsonValues.</returns>
  633. public virtual BsonValue[] ToArray()
  634. {
  635. return _values.ToArray();
  636. }
  637. /// <summary>
  638. /// Converts the BsonArray to a list of BsonValues.
  639. /// </summary>
  640. /// <returns>A list of BsonValues.</returns>
  641. public virtual List<BsonValue> ToList()
  642. {
  643. return _values.ToList();
  644. }
  645. /// <summary>
  646. /// Returns a string representation of the array.
  647. /// </summary>
  648. /// <returns>A string representation of the array.</returns>
  649. public override string ToString()
  650. {
  651. var sb = new StringBuilder();
  652. sb.Append("[");
  653. for (int i = 0; i < _values.Count; i++)
  654. {
  655. if (i > 0) { sb.Append(", "); }
  656. sb.Append(_values[i].ToString());
  657. }
  658. sb.Append("]");
  659. return sb.ToString();
  660. }
  661. // explicit interface implementations
  662. // our version of Add returns BsonArray
  663. void ICollection<BsonValue>.Add(BsonValue value)
  664. {
  665. Add(value);
  666. }
  667. IEnumerator IEnumerable.GetEnumerator()
  668. {
  669. return GetEnumerator();
  670. }
  671. }
  672. }