BsonArray.cs 29 KB

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