经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » MongoDB » 查看文章
.NET生成MongoDB中的主键ObjectId
来源:cnblogs  作者:追逐时光者  时间:2023/3/24 9:05:51  对本文有异议

前言

  因为很多场景下我们需要在创建MongoDB数据的时候提前生成好主键为了返回或者通过主键查询创建的业务,像EF中我们可以生成Guid来,本来想着要不要实现一套MongoDB中ObjectId的,结果发现网上各种各样的实现都有,不过好在阅读C#MongoDB驱动mongo-csharp-driver代码的时候发现有ObjectId.GenerateNewId()的方法提供,我们可以直接调用即可,不需要我们在花费多余的时间设计重写了。

MongoDB ObjectId类型概述

 每次插入一条数据系统都会自动插入一个_id键,键值不可以重复,它可以是任何类型的,也可以手动的插入,默认情况下它的数据类型是ObjectId,由于MongoDB在设计之初就是用作分布式数据库,所以使用ObjectId可以避免不同数据库中_id的重复(如果使用自增的方式在分布式系统中就会出现重复的_id的值)。
ObjectId使用12字节的存储空间,每个字节可以存储两个十六进制数字,所以一共可以存储24个十六进制数字组成的字符串,在这24个字符串中,前8位表示时间戳,接下来6位是一个机器码,接下来4位表示进程id,最后6位表示计数器。

  1. 601e2b6b a3203c c89f 2d31aa
  2. 时间戳 机器码 进程ID 随机数

MongoDB.Driver驱动安装

1、直接命令自动安装

  1. Install-Package MongoDB.Driver

2、搜索Nuget手动安装

调用生成主键ObjectId

  1. var primarykeyId = ObjectId.GenerateNewId();
    //输出:641c54b2e674000035001dc2

mongo-csharp-driver ObjectId详解

关于ObjectId的生成原理大家阅读如下源码即可。

源码地址:https://github.com/mongodb/mongo-csharp-driver/blob/ec74978f7e827515f29cc96fba0c727828e8df7c/src/MongoDB.Bson/ObjectModel/ObjectId.cs

  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.  
  16. using System;
  17. using System.Diagnostics;
  18. using System.Runtime.CompilerServices;
  19. using System.Security;
  20. using System.Threading;
  21. namespace MongoDB.Bson
  22. {
  23. /// <summary>
  24. /// Represents an ObjectId (see also BsonObjectId).
  25. /// </summary>
  26. #if NET45
  27. [Serializable]
  28. #endif
  29. public struct ObjectId : IComparable<ObjectId>, IEquatable<ObjectId>, IConvertible
  30. {
  31. // private static fields
  32. private static readonly ObjectId __emptyInstance = default(ObjectId);
  33. private static readonly int __staticMachine = (GetMachineHash() + GetAppDomainId()) & 0x00ffffff;
  34. private static readonly short __staticPid = GetPid();
  35. private static int __staticIncrement = (new Random()).Next();
  36. // private fields
  37. private readonly int _a;
  38. private readonly int _b;
  39. private readonly int _c;
  40. // constructors
  41. /// <summary>
  42. /// Initializes a new instance of the ObjectId class.
  43. /// </summary>
  44. /// <param name="bytes">The bytes.</param>
  45. public ObjectId(byte[] bytes)
  46. {
  47. if (bytes == null)
  48. {
  49. throw new ArgumentNullException("bytes");
  50. }
  51. if (bytes.Length != 12)
  52. {
  53. throw new ArgumentException("Byte array must be 12 bytes long", "bytes");
  54. }
  55. FromByteArray(bytes, 0, out _a, out _b, out _c);
  56. }
  57. /// <summary>
  58. /// Initializes a new instance of the ObjectId class.
  59. /// </summary>
  60. /// <param name="bytes">The bytes.</param>
  61. /// <param name="index">The index into the byte array where the ObjectId starts.</param>
  62. internal ObjectId(byte[] bytes, int index)
  63. {
  64. FromByteArray(bytes, index, out _a, out _b, out _c);
  65. }
  66. /// <summary>
  67. /// Initializes a new instance of the ObjectId class.
  68. /// </summary>
  69. /// <param name="timestamp">The timestamp (expressed as a DateTime).</param>
  70. /// <param name="machine">The machine hash.</param>
  71. /// <param name="pid">The PID.</param>
  72. /// <param name="increment">The increment.</param>
  73. public ObjectId(DateTime timestamp, int machine, short pid, int increment)
  74. : this(GetTimestampFromDateTime(timestamp), machine, pid, increment)
  75. {
  76. }
  77. /// <summary>
  78. /// Initializes a new instance of the ObjectId class.
  79. /// </summary>
  80. /// <param name="timestamp">The timestamp.</param>
  81. /// <param name="machine">The machine hash.</param>
  82. /// <param name="pid">The PID.</param>
  83. /// <param name="increment">The increment.</param>
  84. public ObjectId(int timestamp, int machine, short pid, int increment)
  85. {
  86. if ((machine & 0xff000000) != 0)
  87. {
  88. throw new ArgumentOutOfRangeException("machine", "The machine value must be between 0 and 16777215 (it must fit in 3 bytes).");
  89. }
  90. if ((increment & 0xff000000) != 0)
  91. {
  92. throw new ArgumentOutOfRangeException("increment", "The increment value must be between 0 and 16777215 (it must fit in 3 bytes).");
  93. }
  94. _a = timestamp;
  95. _b = (machine << 8) | (((int)pid >> 8) & 0xff);
  96. _c = ((int)pid << 24) | increment;
  97. }
  98. /// <summary>
  99. /// Initializes a new instance of the ObjectId class.
  100. /// </summary>
  101. /// <param name="value">The value.</param>
  102. public ObjectId(string value)
  103. {
  104. if (value == null)
  105. {
  106. throw new ArgumentNullException("value");
  107. }
  108. var bytes = BsonUtils.ParseHexString(value);
  109. FromByteArray(bytes, 0, out _a, out _b, out _c);
  110. }
  111. // public static properties
  112. /// <summary>
  113. /// Gets an instance of ObjectId where the value is empty.
  114. /// </summary>
  115. public static ObjectId Empty
  116. {
  117. get { return __emptyInstance; }
  118. }
  119. // public properties
  120. /// <summary>
  121. /// Gets the timestamp.
  122. /// </summary>
  123. public int Timestamp
  124. {
  125. get { return _a; }
  126. }
  127. /// <summary>
  128. /// Gets the machine.
  129. /// </summary>
  130. public int Machine
  131. {
  132. get { return (_b >> 8) & 0xffffff; }
  133. }
  134. /// <summary>
  135. /// Gets the PID.
  136. /// </summary>
  137. public short Pid
  138. {
  139. get { return (short)(((_b << 8) & 0xff00) | ((_c >> 24) & 0x00ff)); }
  140. }
  141. /// <summary>
  142. /// Gets the increment.
  143. /// </summary>
  144. public int Increment
  145. {
  146. get { return _c & 0xffffff; }
  147. }
  148. /// <summary>
  149. /// Gets the creation time (derived from the timestamp).
  150. /// </summary>
  151. public DateTime CreationTime
  152. {
  153. get { return BsonConstants.UnixEpoch.AddSeconds(Timestamp); }
  154. }
  155. // public operators
  156. /// <summary>
  157. /// Compares two ObjectIds.
  158. /// </summary>
  159. /// <param name="lhs">The first ObjectId.</param>
  160. /// <param name="rhs">The other ObjectId</param>
  161. /// <returns>True if the first ObjectId is less than the second ObjectId.</returns>
  162. public static bool operator <(ObjectId lhs, ObjectId rhs)
  163. {
  164. return lhs.CompareTo(rhs) < 0;
  165. }
  166. /// <summary>
  167. /// Compares two ObjectIds.
  168. /// </summary>
  169. /// <param name="lhs">The first ObjectId.</param>
  170. /// <param name="rhs">The other ObjectId</param>
  171. /// <returns>True if the first ObjectId is less than or equal to the second ObjectId.</returns>
  172. public static bool operator <=(ObjectId lhs, ObjectId rhs)
  173. {
  174. return lhs.CompareTo(rhs) <= 0;
  175. }
  176. /// <summary>
  177. /// Compares two ObjectIds.
  178. /// </summary>
  179. /// <param name="lhs">The first ObjectId.</param>
  180. /// <param name="rhs">The other ObjectId.</param>
  181. /// <returns>True if the two ObjectIds are equal.</returns>
  182. public static bool operator ==(ObjectId lhs, ObjectId rhs)
  183. {
  184. return lhs.Equals(rhs);
  185. }
  186. /// <summary>
  187. /// Compares two ObjectIds.
  188. /// </summary>
  189. /// <param name="lhs">The first ObjectId.</param>
  190. /// <param name="rhs">The other ObjectId.</param>
  191. /// <returns>True if the two ObjectIds are not equal.</returns>
  192. public static bool operator !=(ObjectId lhs, ObjectId rhs)
  193. {
  194. return !(lhs == rhs);
  195. }
  196. /// <summary>
  197. /// Compares two ObjectIds.
  198. /// </summary>
  199. /// <param name="lhs">The first ObjectId.</param>
  200. /// <param name="rhs">The other ObjectId</param>
  201. /// <returns>True if the first ObjectId is greather than or equal to the second ObjectId.</returns>
  202. public static bool operator >=(ObjectId lhs, ObjectId rhs)
  203. {
  204. return lhs.CompareTo(rhs) >= 0;
  205. }
  206. /// <summary>
  207. /// Compares two ObjectIds.
  208. /// </summary>
  209. /// <param name="lhs">The first ObjectId.</param>
  210. /// <param name="rhs">The other ObjectId</param>
  211. /// <returns>True if the first ObjectId is greather than the second ObjectId.</returns>
  212. public static bool operator >(ObjectId lhs, ObjectId rhs)
  213. {
  214. return lhs.CompareTo(rhs) > 0;
  215. }
  216. // public static methods
  217. /// <summary>
  218. /// Generates a new ObjectId with a unique value.
  219. /// </summary>
  220. /// <returns>An ObjectId.</returns>
  221. public static ObjectId GenerateNewId()
  222. {
  223. return GenerateNewId(GetTimestampFromDateTime(DateTime.UtcNow));
  224. }
  225. /// <summary>
  226. /// Generates a new ObjectId with a unique value (with the timestamp component based on a given DateTime).
  227. /// </summary>
  228. /// <param name="timestamp">The timestamp component (expressed as a DateTime).</param>
  229. /// <returns>An ObjectId.</returns>
  230. public static ObjectId GenerateNewId(DateTime timestamp)
  231. {
  232. return GenerateNewId(GetTimestampFromDateTime(timestamp));
  233. }
  234. /// <summary>
  235. /// Generates a new ObjectId with a unique value (with the given timestamp).
  236. /// </summary>
  237. /// <param name="timestamp">The timestamp component.</param>
  238. /// <returns>An ObjectId.</returns>
  239. public static ObjectId GenerateNewId(int timestamp)
  240. {
  241. int increment = Interlocked.Increment(ref __staticIncrement) & 0x00ffffff; // only use low order 3 bytes
  242. return new ObjectId(timestamp, __staticMachine, __staticPid, increment);
  243. }
  244. /// <summary>
  245. /// Packs the components of an ObjectId into a byte array.
  246. /// </summary>
  247. /// <param name="timestamp">The timestamp.</param>
  248. /// <param name="machine">The machine hash.</param>
  249. /// <param name="pid">The PID.</param>
  250. /// <param name="increment">The increment.</param>
  251. /// <returns>A byte array.</returns>
  252. public static byte[] Pack(int timestamp, int machine, short pid, int increment)
  253. {
  254. if ((machine & 0xff000000) != 0)
  255. {
  256. throw new ArgumentOutOfRangeException("machine", "The machine value must be between 0 and 16777215 (it must fit in 3 bytes).");
  257. }
  258. if ((increment & 0xff000000) != 0)
  259. {
  260. throw new ArgumentOutOfRangeException("increment", "The increment value must be between 0 and 16777215 (it must fit in 3 bytes).");
  261. }
  262. byte[] bytes = new byte[12];
  263. bytes[0] = (byte)(timestamp >> 24);
  264. bytes[1] = (byte)(timestamp >> 16);
  265. bytes[2] = (byte)(timestamp >> 8);
  266. bytes[3] = (byte)(timestamp);
  267. bytes[4] = (byte)(machine >> 16);
  268. bytes[5] = (byte)(machine >> 8);
  269. bytes[6] = (byte)(machine);
  270. bytes[7] = (byte)(pid >> 8);
  271. bytes[8] = (byte)(pid);
  272. bytes[9] = (byte)(increment >> 16);
  273. bytes[10] = (byte)(increment >> 8);
  274. bytes[11] = (byte)(increment);
  275. return bytes;
  276. }
  277. /// <summary>
  278. /// Parses a string and creates a new ObjectId.
  279. /// </summary>
  280. /// <param name="s">The string value.</param>
  281. /// <returns>A ObjectId.</returns>
  282. public static ObjectId Parse(string s)
  283. {
  284. if (s == null)
  285. {
  286. throw new ArgumentNullException("s");
  287. }
  288. ObjectId objectId;
  289. if (TryParse(s, out objectId))
  290. {
  291. return objectId;
  292. }
  293. else
  294. {
  295. var message = string.Format("'{0}' is not a valid 24 digit hex string.", s);
  296. throw new FormatException(message);
  297. }
  298. }
  299. /// <summary>
  300. /// Tries to parse a string and create a new ObjectId.
  301. /// </summary>
  302. /// <param name="s">The string value.</param>
  303. /// <param name="objectId">The new ObjectId.</param>
  304. /// <returns>True if the string was parsed successfully.</returns>
  305. public static bool TryParse(string s, out ObjectId objectId)
  306. {
  307. // don't throw ArgumentNullException if s is null
  308. if (s != null && s.Length == 24)
  309. {
  310. byte[] bytes;
  311. if (BsonUtils.TryParseHexString(s, out bytes))
  312. {
  313. objectId = new ObjectId(bytes);
  314. return true;
  315. }
  316. }
  317. objectId = default(ObjectId);
  318. return false;
  319. }
  320. /// <summary>
  321. /// Unpacks a byte array into the components of an ObjectId.
  322. /// </summary>
  323. /// <param name="bytes">A byte array.</param>
  324. /// <param name="timestamp">The timestamp.</param>
  325. /// <param name="machine">The machine hash.</param>
  326. /// <param name="pid">The PID.</param>
  327. /// <param name="increment">The increment.</param>
  328. public static void Unpack(byte[] bytes, out int timestamp, out int machine, out short pid, out int increment)
  329. {
  330. if (bytes == null)
  331. {
  332. throw new ArgumentNullException("bytes");
  333. }
  334. if (bytes.Length != 12)
  335. {
  336. throw new ArgumentOutOfRangeException("bytes", "Byte array must be 12 bytes long.");
  337. }
  338. timestamp = (bytes[0] << 24) + (bytes[1] << 16) + (bytes[2] << 8) + bytes[3];
  339. machine = (bytes[4] << 16) + (bytes[5] << 8) + bytes[6];
  340. pid = (short)((bytes[7] << 8) + bytes[8]);
  341. increment = (bytes[9] << 16) + (bytes[10] << 8) + bytes[11];
  342. }
  343. // private static methods
  344. private static int GetAppDomainId()
  345. {
  346. #if NETSTANDARD1_5 || NETSTANDARD1_6
  347. return 1;
  348. #else
  349. return AppDomain.CurrentDomain.Id;
  350. #endif
  351. }
  352. /// <summary>
  353. /// Gets the current process id. This method exists because of how CAS operates on the call stack, checking
  354. /// for permissions before executing the method. Hence, if we inlined this call, the calling method would not execute
  355. /// before throwing an exception requiring the try/catch at an even higher level that we don't necessarily control.
  356. /// </summary>
  357. [MethodImpl(MethodImplOptions.NoInlining)]
  358. private static int GetCurrentProcessId()
  359. {
  360. return Process.GetCurrentProcess().Id;
  361. }
  362. private static int GetMachineHash()
  363. {
  364. // use instead of Dns.HostName so it will work offline
  365. var machineName = GetMachineName();
  366. return 0x00ffffff & machineName.GetHashCode(); // use first 3 bytes of hash
  367. }
  368. private static string GetMachineName()
  369. {
  370. return Environment.MachineName;
  371. }
  372. private static short GetPid()
  373. {
  374. try
  375. {
  376. return (short)GetCurrentProcessId(); // use low order two bytes only
  377. }
  378. catch (SecurityException)
  379. {
  380. return 0;
  381. }
  382. }
  383. private static int GetTimestampFromDateTime(DateTime timestamp)
  384. {
  385. var secondsSinceEpoch = (long)Math.Floor((BsonUtils.ToUniversalTime(timestamp) - BsonConstants.UnixEpoch).TotalSeconds);
  386. if (secondsSinceEpoch < int.MinValue || secondsSinceEpoch > int.MaxValue)
  387. {
  388. throw new ArgumentOutOfRangeException("timestamp");
  389. }
  390. return (int)secondsSinceEpoch;
  391. }
  392. private static void FromByteArray(byte[] bytes, int offset, out int a, out int b, out int c)
  393. {
  394. a = (bytes[offset] << 24) | (bytes[offset + 1] << 16) | (bytes[offset + 2] << 8) | bytes[offset + 3];
  395. b = (bytes[offset + 4] << 24) | (bytes[offset + 5] << 16) | (bytes[offset + 6] << 8) | bytes[offset + 7];
  396. c = (bytes[offset + 8] << 24) | (bytes[offset + 9] << 16) | (bytes[offset + 10] << 8) | bytes[offset + 11];
  397. }
  398. // public methods
  399. /// <summary>
  400. /// Compares this ObjectId to another ObjectId.
  401. /// </summary>
  402. /// <param name="other">The other ObjectId.</param>
  403. /// <returns>A 32-bit signed integer that indicates whether this ObjectId is less than, equal to, or greather than the other.</returns>
  404. public int CompareTo(ObjectId other)
  405. {
  406. int result = ((uint)_a).CompareTo((uint)other._a);
  407. if (result != 0) { return result; }
  408. result = ((uint)_b).CompareTo((uint)other._b);
  409. if (result != 0) { return result; }
  410. return ((uint)_c).CompareTo((uint)other._c);
  411. }
  412. /// <summary>
  413. /// Compares this ObjectId to another ObjectId.
  414. /// </summary>
  415. /// <param name="rhs">The other ObjectId.</param>
  416. /// <returns>True if the two ObjectIds are equal.</returns>
  417. public bool Equals(ObjectId rhs)
  418. {
  419. return
  420. _a == rhs._a &&
  421. _b == rhs._b &&
  422. _c == rhs._c;
  423. }
  424. /// <summary>
  425. /// Compares this ObjectId to another object.
  426. /// </summary>
  427. /// <param name="obj">The other object.</param>
  428. /// <returns>True if the other object is an ObjectId and equal to this one.</returns>
  429. public override bool Equals(object obj)
  430. {
  431. if (obj is ObjectId)
  432. {
  433. return Equals((ObjectId)obj);
  434. }
  435. else
  436. {
  437. return false;
  438. }
  439. }
  440. /// <summary>
  441. /// Gets the hash code.
  442. /// </summary>
  443. /// <returns>The hash code.</returns>
  444. public override int GetHashCode()
  445. {
  446. int hash = 17;
  447. hash = 37 * hash + _a.GetHashCode();
  448. hash = 37 * hash + _b.GetHashCode();
  449. hash = 37 * hash + _c.GetHashCode();
  450. return hash;
  451. }
  452. /// <summary>
  453. /// Converts the ObjectId to a byte array.
  454. /// </summary>
  455. /// <returns>A byte array.</returns>
  456. public byte[] ToByteArray()
  457. {
  458. var bytes = new byte[12];
  459. ToByteArray(bytes, 0);
  460. return bytes;
  461. }
  462. /// <summary>
  463. /// Converts the ObjectId to a byte array.
  464. /// </summary>
  465. /// <param name="destination">The destination.</param>
  466. /// <param name="offset">The offset.</param>
  467. public void ToByteArray(byte[] destination, int offset)
  468. {
  469. if (destination == null)
  470. {
  471. throw new ArgumentNullException("destination");
  472. }
  473. if (offset + 12 > destination.Length)
  474. {
  475. throw new ArgumentException("Not enough room in destination buffer.", "offset");
  476. }
  477. destination[offset + 0] = (byte)(_a >> 24);
  478. destination[offset + 1] = (byte)(_a >> 16);
  479. destination[offset + 2] = (byte)(_a >> 8);
  480. destination[offset + 3] = (byte)(_a);
  481. destination[offset + 4] = (byte)(_b >> 24);
  482. destination[offset + 5] = (byte)(_b >> 16);
  483. destination[offset + 6] = (byte)(_b >> 8);
  484. destination[offset + 7] = (byte)(_b);
  485. destination[offset + 8] = (byte)(_c >> 24);
  486. destination[offset + 9] = (byte)(_c >> 16);
  487. destination[offset + 10] = (byte)(_c >> 8);
  488. destination[offset + 11] = (byte)(_c);
  489. }
  490. /// <summary>
  491. /// Returns a string representation of the value.
  492. /// </summary>
  493. /// <returns>A string representation of the value.</returns>
  494. public override string ToString()
  495. {
  496. var c = new char[24];
  497. c[0] = BsonUtils.ToHexChar((_a >> 28) & 0x0f);
  498. c[1] = BsonUtils.ToHexChar((_a >> 24) & 0x0f);
  499. c[2] = BsonUtils.ToHexChar((_a >> 20) & 0x0f);
  500. c[3] = BsonUtils.ToHexChar((_a >> 16) & 0x0f);
  501. c[4] = BsonUtils.ToHexChar((_a >> 12) & 0x0f);
  502. c[5] = BsonUtils.ToHexChar((_a >> 8) & 0x0f);
  503. c[6] = BsonUtils.ToHexChar((_a >> 4) & 0x0f);
  504. c[7] = BsonUtils.ToHexChar(_a & 0x0f);
  505. c[8] = BsonUtils.ToHexChar((_b >> 28) & 0x0f);
  506. c[9] = BsonUtils.ToHexChar((_b >> 24) & 0x0f);
  507. c[10] = BsonUtils.ToHexChar((_b >> 20) & 0x0f);
  508. c[11] = BsonUtils.ToHexChar((_b >> 16) & 0x0f);
  509. c[12] = BsonUtils.ToHexChar((_b >> 12) & 0x0f);
  510. c[13] = BsonUtils.ToHexChar((_b >> 8) & 0x0f);
  511. c[14] = BsonUtils.ToHexChar((_b >> 4) & 0x0f);
  512. c[15] = BsonUtils.ToHexChar(_b & 0x0f);
  513. c[16] = BsonUtils.ToHexChar((_c >> 28) & 0x0f);
  514. c[17] = BsonUtils.ToHexChar((_c >> 24) & 0x0f);
  515. c[18] = BsonUtils.ToHexChar((_c >> 20) & 0x0f);
  516. c[19] = BsonUtils.ToHexChar((_c >> 16) & 0x0f);
  517. c[20] = BsonUtils.ToHexChar((_c >> 12) & 0x0f);
  518. c[21] = BsonUtils.ToHexChar((_c >> 8) & 0x0f);
  519. c[22] = BsonUtils.ToHexChar((_c >> 4) & 0x0f);
  520. c[23] = BsonUtils.ToHexChar(_c & 0x0f);
  521. return new string(c);
  522. }
  523. // explicit IConvertible implementation
  524. TypeCode IConvertible.GetTypeCode()
  525. {
  526. return TypeCode.Object;
  527. }
  528. bool IConvertible.ToBoolean(IFormatProvider provider)
  529. {
  530. throw new InvalidCastException();
  531. }
  532. byte IConvertible.ToByte(IFormatProvider provider)
  533. {
  534. throw new InvalidCastException();
  535. }
  536. char IConvertible.ToChar(IFormatProvider provider)
  537. {
  538. throw new InvalidCastException();
  539. }
  540. DateTime IConvertible.ToDateTime(IFormatProvider provider)
  541. {
  542. throw new InvalidCastException();
  543. }
  544. decimal IConvertible.ToDecimal(IFormatProvider provider)
  545. {
  546. throw new InvalidCastException();
  547. }
  548. double IConvertible.ToDouble(IFormatProvider provider)
  549. {
  550. throw new InvalidCastException();
  551. }
  552. short IConvertible.ToInt16(IFormatProvider provider)
  553. {
  554. throw new InvalidCastException();
  555. }
  556. int IConvertible.ToInt32(IFormatProvider provider)
  557. {
  558. throw new InvalidCastException();
  559. }
  560. long IConvertible.ToInt64(IFormatProvider provider)
  561. {
  562. throw new InvalidCastException();
  563. }
  564. sbyte IConvertible.ToSByte(IFormatProvider provider)
  565. {
  566. throw new InvalidCastException();
  567. }
  568. float IConvertible.ToSingle(IFormatProvider provider)
  569. {
  570. throw new InvalidCastException();
  571. }
  572. string IConvertible.ToString(IFormatProvider provider)
  573. {
  574. return ToString();
  575. }
  576. object IConvertible.ToType(Type conversionType, IFormatProvider provider)
  577. {
  578. switch (Type.GetTypeCode(conversionType))
  579. {
  580. case TypeCode.String:
  581. return ((IConvertible)this).ToString(provider);
  582. case TypeCode.Object:
  583. if (conversionType == typeof(object) || conversionType == typeof(ObjectId))
  584. {
  585. return this;
  586. }
  587. if (conversionType == typeof(BsonObjectId))
  588. {
  589. return new BsonObjectId(this);
  590. }
  591. if (conversionType == typeof(BsonString))
  592. {
  593. return new BsonString(((IConvertible)this).ToString(provider));
  594. }
  595. break;
  596. }
  597. throw new InvalidCastException();
  598. }
  599. ushort IConvertible.ToUInt16(IFormatProvider provider)
  600. {
  601. throw new InvalidCastException();
  602. }
  603. uint IConvertible.ToUInt32(IFormatProvider provider)
  604. {
  605. throw new InvalidCastException();
  606. }
  607. ulong IConvertible.ToUInt64(IFormatProvider provider)
  608. {
  609. throw new InvalidCastException();
  610. }
  611. }
  612. }

 

 

 

原文链接:https://www.cnblogs.com/Can-daydayup/p/17249852.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号