BsonArray.cs 25 KB

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