最新代码在这儿:CombGuid.cs

首先这里不做GUID与整形作为主键的优劣之争,GUID自有它优势,但GUID本身是乱序的,会对索引的维护带来性能上的损耗,数据量越大越明显。

COMB 类型 GUID 是由Jimmy Nilsson在他的“The Cost of GUIDs as Primary Keys”一文中设计出来的。

基本设计思路是这样的:既然GUID数据因毫无规律可言造成索引效率低下,影响了系统的性能,那么能不能通过组合的方式,保留GUID的前10个字节,用后6个字节表示GUID生成的时间(DateTime),这样我们将时间信息与GUID组合起来,在保留GUID的唯一性的同时增加了有序性,以此来提高索引效率。

在NHibernate已经有代码实现,基于1/300秒为单位生成的,但实际Windows操作系统时钟更新频率多核15ms(1/67秒),单核10ms,是无法精确到1/300秒的,而且在短时间内生成大量CombGuid时,DateTime.Now有可能是不变化的,我在测试中遇到了这种情况,结果生成了5万条CombGuid记录,其中有两万多条是重复的,这样在实际生产环境中如果数据插入量非常大而且频繁的情况下,CombGuid排序的优势就没有了。

针对NHibernate的代码进行了些优化,已当前时间1/10000秒为基础创建CombGuid,如果当前时间基数与上次创建时相同,直接累加1,确保不产生重复的CombGuid:

  1. private static readonly DateTime _CombBaseDate = new DateTime(1900, 1, 1);
  2. private static Int32 _LastDays; // 天数
  3. private static Int32 _LastTenthMilliseconds; // 单位:1/10 毫秒
  4. private static readonly Int32 _MaxTenthMilliseconds = 863999999;
  5.  
  6. #region - NewComb -
  7.  
  8. /// <summary>初始化 CombGuid 结构的新实例。</summary>
  9. /// <returns>一个新的 CombGuid 对象。</returns>
  10. public static CombGuid NewComb()
  11. {
  12. var guidArray = Guid.NewGuid().ToByteArray();
  13.  
  14. var now = DateTime.Now;
  15.  
  16. // Get the days and milliseconds which will be used to build the Byte String
  17. var days = new TimeSpan(now.Ticks - _CombBaseDate.Ticks).Days;
  18. var tenthMilliseconds = (Int32)(now.TimeOfDay.TotalMilliseconds * 10D);
  19. var lastDays = _LastDays;
  20. var lastTenthMilliseconds = _LastTenthMilliseconds;
  21. if (days > lastDays)
  22. {
  23. Interlocked.CompareExchange(ref _LastDays, days, lastDays);
  24. Interlocked.CompareExchange(ref _LastTenthMilliseconds, tenthMilliseconds, lastTenthMilliseconds);
  25. }
  26. else
  27. {
  28. if (tenthMilliseconds > lastTenthMilliseconds)
  29. {
  30. Interlocked.CompareExchange(ref _LastTenthMilliseconds, tenthMilliseconds, lastTenthMilliseconds);
  31. }
  32. else
  33. {
  34. if (_LastTenthMilliseconds < Int32.MaxValue) { Interlocked.Increment(ref _LastTenthMilliseconds); }
  35. tenthMilliseconds = _LastTenthMilliseconds;
  36. }
  37. }
  38. // Convert to a Byte array
  39. var daysArray = BitConverter.GetBytes(days);
  40. var msecsArray = BitConverter.GetBytes(tenthMilliseconds);
  41.  
  42. // Reverse the bytes to match SQL Servers ordering
  43. Array.Reverse(daysArray);
  44. Array.Reverse(msecsArray);
  45.  
  46. // Copy the bytes into the guid
  47. Array.Copy(daysArray, daysArray.Length - 2, guidArray, guidArray.Length - 6, 2);
  48. //Array.Copy(msecsArray, msecsArray.Length - 4, guidArray, guidArray.Length - 4, 4);
  49. Array.Copy(msecsArray, 0, guidArray, guidArray.Length - 4, 4);
  50.  
  51. return new CombGuid(guidArray, true);
  52. }
  53.  
  54. #endregion

这样理论上一天之内允许生成 864000000 个不重复的CombGuid;如果当天生成的个数大于 864000000 ,会一直累加 1 直到 2147483647 ,也就是说实际一天之内能生成 2147483647 个不重复的CombGuid。

完整CombGuid代码,参考了.net fx内部guid、sqlguid的部分方法:

  1. /*
  2. * CombGuid
  3. *
  4. * 作者:海洋饼干
  5. * 时间:2014-09-10 18:42:51
  6. * 博客:http://www.cnblogs.com/hmking/
  7. * 版权:版权所有 (C) Eme Development Team 2014
  8. */
  9.  
  10. using System;
  11. using System.Collections.Generic;
  12. using System.ComponentModel;
  13. using System.Data.SqlTypes;
  14. using System.Runtime.InteropServices;
  15. using System.Threading;
  16. using System.Xml;
  17. using System.Xml.Schema;
  18. using System.Xml.Serialization;
  19.  
  20. namespace HmFramework
  21. {
  22. /// <summary>COMB 类型 GUID,要存储在数据库中或要从数据库中检索的 GUID。</summary>
  23. /// <remarks>COMB 类型 GUID 是由Jimmy Nilsson在他的“The Cost of GUIDs as Primary Keys”一文中设计出来的。
  24. /// <para>基本设计思路是这样的:既然GUID数据因毫无规律可言造成索引效率低下,影响了系统的性能,那么能不能通过组合的方式,
  25. /// 保留GUID的前10个字节,用后6个字节表示GUID生成的时间(DateTime),这样我们将时间信息与GUID组合起来,
  26. /// 在保留GUID的唯一性的同时增加了有序性,以此来提高索引效率。</para>
  27. /// <para>也许有人会担心GUID减少到10字节会造成数据出现重复,其实不用担心,
  28. /// 后6字节的时间精度可以达到 1/10000 秒,两个COMB类型数据完全相同的可能性是在这 1/10000 秒内生成的两个GUID前10个字节完全相同,这几乎是不可能的!</para>
  29. /// <para>理论上一天之内允许生成 864000000 个不重复的CombGuid;如果当天生成的个数大于 864000000 ,会一直累加 1 直到 2147483647 ,
  30. /// 也就是说实际一天之内能生成 2147483647 个不重复的CombGuid。</para>
  31. /// </remarks>
  32. public struct CombGuid : INullable, IComparable, IComparable<CombGuid>, IEquatable<CombGuid>, IXmlSerializable
  33. {
  34. #region -- Fields --
  35.  
  36. private static readonly String _NullString = "nil";
  37.  
  38. private static readonly Int32 _SizeOfGuid = 16;
  39.  
  40. // Comparison orders.
  41. private static readonly Int32[] _GuidComparisonOrders = new Int32[16] { 10, 11, 12, 13, 14, 15, 8, 9, 6, 7, 4, 5, 0, 1, 2, 3 };
  42.  
  43. // Parse orders.
  44. private static readonly Int32[] _GuidParseOrders32 = new Int32[32]
  45. {
  46. 30, 31, 28, 29, 26, 27, 24, 25,
  47. 22, 23, 20, 21,
  48. 18, 19, 16, 17,
  49. 12, 13, 14, 15,
  50. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
  51. };
  52. private static readonly Int32[] _GuidParseOrders36 = new Int32[36]
  53. {
  54. 34, 35, 32, 33, 30, 31, 28, 29,
  55. 27,
  56. 25, 26, 23, 24,
  57. 22,
  58. 20, 21, 18, 19,
  59. 17,
  60. 13, 14, 15, 16,
  61. 12,
  62. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
  63. };
  64.  
  65. // the CombGuid is null if m_value is null
  66. private Byte[] m_value;
  67.  
  68. #endregion
  69.  
  70. #region -- 属性 --
  71.  
  72. /// <summary>CombGuid 结构的只读实例,其值空。</summary>
  73. public static readonly CombGuid Null = new CombGuid(true);
  74.  
  75. /// <summary>获取 CombGuid 结构的值。 此属性为只读。</summary>
  76. public Guid Value
  77. {
  78. get
  79. {
  80. if (IsNull)
  81. {
  82. throw new SqlNullValueException();
  83. }
  84. else
  85. {
  86. return new Guid(m_value);
  87. }
  88. }
  89. }
  90.  
  91. /// <summary>获取 CombGuid 结构的日期时间属性。
  92. /// <para>如果同一时间批量生成了大量的 CombGuid 时,返回的日期时间是不准确的!</para>
  93. /// </summary>
  94. public DateTime DateTime
  95. {
  96. get
  97. {
  98. if (IsNull)
  99. {
  100. throw new SqlNullValueException();
  101. }
  102. else
  103. {
  104. var daysArray = new Byte[4];
  105. var msecsArray = new Byte[4];
  106.  
  107. // Copy the date parts of the guid to the respective Byte arrays.
  108. Array.Copy(m_value, m_value.Length - 6, daysArray, 2, 2);
  109. Array.Copy(m_value, m_value.Length - 4, msecsArray, 0, 4);
  110.  
  111. // Reverse the arrays to put them into the appropriate order
  112. Array.Reverse(daysArray);
  113. Array.Reverse(msecsArray);
  114.  
  115. // Convert the bytes to ints
  116. var days = BitConverter.ToInt32(daysArray, 0);
  117. var msecs = BitConverter.ToInt32(msecsArray, 0);
  118.  
  119. var date = _CombBaseDate.AddDays(days);
  120. if (msecs > _MaxTenthMilliseconds) { msecs = _MaxTenthMilliseconds; }
  121. msecs /= 10;
  122. return date.AddMilliseconds(msecs);
  123. }
  124. }
  125. }
  126.  
  127. #endregion
  128.  
  129. #region -- 构造 --
  130.  
  131. /// <summary>实例化一个空 CombGuid 结构</summary>
  132. private CombGuid(Boolean isNull)
  133. {
  134. m_value = null;
  135. }
  136.  
  137. /// <summary>使用指定的字节数组初始化 CombGuid 结构的新实例。</summary>
  138. /// <param name="value">包含初始化 CombGuid 的值的 16 元素字节数组。</param>
  139. public CombGuid(Byte[] value)
  140. : this(value, false) { }
  141.  
  142. /// <summary>使用指定的字节数组初始化 CombGuid 结构的新实例。</summary>
  143. /// <param name="value">包含初始化 CombGuid 的值的 16 元素字节数组。</param>
  144. /// <param name="isOwner">是否 CombGuid 结构直接使用</param>
  145. private CombGuid(Byte[] value, Boolean isOwner)
  146. {
  147. if (value == null || value.Length != _SizeOfGuid)
  148. {
  149. throw new ArgumentException("value 的长度不是 16 个字节。");
  150. }
  151. if (isOwner)
  152. {
  153. m_value = value;
  154. }
  155. else
  156. {
  157. m_value = new Byte[_SizeOfGuid];
  158. value.CopyTo(m_value, 0);
  159. }
  160. }
  161.  
  162. /// <summary>使用指定字符串所表示的值初始化 CombGuid 结构的新实例。</summary>
  163. /// <param name="comb">包含下面任一格式的 CombGuid 的字符串(“d”表示忽略大小写的十六进制数字):
  164. /// <para>32 个连续的数字 dddddddddddddddddddddddddddddddd </para>
  165. /// <para>- 或 - </para>
  166. /// <para>12 和 4、4、4、8 位数字的分组,各组之间有连线符,dddddddddddd-dddd-dddd-dddd-dddddddd</para>
  167. /// </param>
  168. public CombGuid(String comb)
  169. {
  170. ValidationHelper.ArgumentNullOrEmpty(comb, "comb");
  171.  
  172. Int32 a; Int16 b, c; Byte[] d;
  173. if (new GuidParser(comb).TryParse(out a, out b, out c, out d))
  174. {
  175. m_value = new Byte[_SizeOfGuid];
  176. Init(a, b, c, d);
  177. }
  178. else
  179. {
  180. throw CreateFormatException(comb);
  181. }
  182. }
  183.  
  184. private static Exception CreateFormatException(String s)
  185. {
  186. return new FormatException(String.Format("Invalid CombGuid format: {0}", s));
  187. }
  188.  
  189. /// <summary>使用指定的 Guid 参数初始化 CombGuid 结构的新实例。</summary>
  190. /// <param name="g">一个 Guid</param>
  191. public CombGuid(Guid g)
  192. {
  193. m_value = g.ToByteArray();
  194. }
  195.  
  196. /// <summary>使用指定的整数和字节数组初始化 CombGuid 类的新实例。</summary>
  197. /// <param name="a">CombGuid 的开头四个字节。</param>
  198. /// <param name="b">CombGuid 的下两个字节。</param>
  199. /// <param name="c">CombGuid 的下两个字节。</param>
  200. /// <param name="d">CombGuid 的其余 8 个字节</param>
  201. public CombGuid(Int32 a, Int16 b, Int16 c, Byte[] d)
  202. {
  203. ValidationHelper.ArgumentNull(d, "d");
  204. // Check that array is not too big
  205. if (d.Length != 8) { throw new ArgumentException("d 的长度不是 8 个字节。"); }
  206.  
  207. m_value = new Byte[_SizeOfGuid];
  208. Init(a, b, c, d);
  209. }
  210.  
  211. private void Init(Int32 a, Int16 b, Int16 c, Byte[] d)
  212. {
  213. m_value[0] = (Byte)(a);
  214. m_value[1] = (Byte)(a >> 8);
  215. m_value[2] = (Byte)(a >> 16);
  216. m_value[3] = (Byte)(a >> 24);
  217. m_value[4] = (Byte)(b);
  218. m_value[5] = (Byte)(b >> 8);
  219. m_value[6] = (Byte)(c);
  220. m_value[7] = (Byte)(c >> 8);
  221. m_value[8] = d[0];
  222. m_value[9] = d[1];
  223. m_value[10] = d[2];
  224. m_value[11] = d[3];
  225. m_value[12] = d[4];
  226. m_value[13] = d[5];
  227. m_value[14] = d[6];
  228. m_value[15] = d[7];
  229. }
  230.  
  231. /// <summary>使用指定的值初始化 CombGuid 结构的新实例。</summary>
  232. /// <param name="a">CombGuid 的开头四个字节。</param>
  233. /// <param name="b">CombGuid 的下两个字节。</param>
  234. /// <param name="c">CombGuid 的下两个字节。</param>
  235. /// <param name="d">CombGuid 的下一个字节。</param>
  236. /// <param name="e">CombGuid 的下一个字节。</param>
  237. /// <param name="f">CombGuid 的下一个字节。</param>
  238. /// <param name="g">CombGuid 的下一个字节。</param>
  239. /// <param name="h">CombGuid 的下一个字节。</param>
  240. /// <param name="i">CombGuid 的下一个字节。</param>
  241. /// <param name="j">CombGuid 的下一个字节。</param>
  242. /// <param name="k">CombGuid 的下一个字节。</param>
  243. public CombGuid(Int32 a, Int16 b, Int16 c, Byte d, Byte e, Byte f, Byte g, Byte h, Byte i, Byte j, Byte k)
  244. {
  245. m_value = new Byte[_SizeOfGuid];
  246.  
  247. m_value[0] = (Byte)(a);
  248. m_value[1] = (Byte)(a >> 8);
  249. m_value[2] = (Byte)(a >> 16);
  250. m_value[3] = (Byte)(a >> 24);
  251. m_value[4] = (Byte)(b);
  252. m_value[5] = (Byte)(b >> 8);
  253. m_value[6] = (Byte)(c);
  254. m_value[7] = (Byte)(c >> 8);
  255. m_value[8] = d;
  256. m_value[9] = e;
  257. m_value[10] = f;
  258. m_value[11] = g;
  259. m_value[12] = h;
  260. m_value[13] = i;
  261. m_value[14] = j;
  262. m_value[15] = k;
  263. }
  264.  
  265. #endregion
  266.  
  267. #region -- 方法 --
  268.  
  269. #region - ToByteArray -
  270.  
  271. /// <summary>将此 CombGuid 结构转换为字节数组</summary>
  272. /// <returns>16 元素字节数组。</returns>
  273. public Byte[] ToByteArray()
  274. {
  275. var ret = new Byte[_SizeOfGuid];
  276. m_value.CopyTo(ret, 0);
  277. return ret;
  278. }
  279.  
  280. #endregion
  281.  
  282. #region - GetByteArray -
  283.  
  284. /// <summary>直接获取此 CombGuid 结构内部的字节数组,如果此 CombGuid 为空,返回空值。
  285. /// <para>调用此方法后,不要对获取的字节数组做任何改变!!!</para>
  286. /// </summary>
  287. /// <returns>16 元素字节数组 或 null。</returns>
  288. [EditorBrowsable(EditorBrowsableState.Advanced)]
  289. public Byte[] GetByteArray()
  290. {
  291. return m_value;
  292. }
  293.  
  294. #endregion
  295.  
  296. #region - ToString -
  297.  
  298. /// <summary>已重载,将此 CombGuid 结构转换为字符串。</summary>
  299. /// <returns>返回该 CombGuid 结构的字符串表示形式。</returns>
  300. public override String ToString()
  301. {
  302. return ToString(CombGuidFormatStringType.Comb);
  303. }
  304.  
  305. /// <summary>根据所提供的格式方式,返回此 CombGuid 实例值的字符串表示形式。</summary>
  306. /// <param name="formatType">格式化方式,它指示如何格式化此 CombGuid 的值。</param>
  307. /// <returns>此 CombGuid 的值,用一系列指定格式的小写十六进制位表示</returns>
  308. public String ToString(CombGuidFormatStringType formatType)
  309. {
  310. if (IsNull) { return _NullString; }
  311.  
  312. var offset = 0;
  313. var strLength = 36;
  314. var dash = true;
  315. if (formatType == CombGuidFormatStringType.Guid32Digits || formatType == CombGuidFormatStringType.Comb32Digits)
  316. {
  317. strLength = 32;
  318. dash = false;
  319. }
  320. var guidChars = new Char[strLength];
  321. var isComb = formatType == CombGuidFormatStringType.Comb || formatType == CombGuidFormatStringType.Comb32Digits;
  322.  
  323. #region MS GUID类内部代码
  324.  
  325. //g[0] = (Byte)(_a);
  326. //g[1] = (Byte)(_a >> 8);
  327. //g[2] = (Byte)(_a >> 16);
  328. //g[3] = (Byte)(_a >> 24);
  329. //g[4] = (Byte)(_b);
  330. //g[5] = (Byte)(_b >> 8);
  331. //g[6] = (Byte)(_c);
  332. //g[7] = (Byte)(_c >> 8);
  333. //g[8] = _d;
  334. //g[9] = _e;
  335. //g[10] = _f;
  336. //g[11] = _g;
  337. //g[12] = _h;
  338. //g[13] = _i;
  339. //g[14] = _j;
  340. //g[15] = _k;
  341. //// [{|(]dddddddd[-]dddd[-]dddd[-]dddd[-]dddddddddddd[}|)]
  342. //offset = HexsToChars(guidChars, offset, _a >> 24, _a >> 16);
  343. //offset = HexsToChars(guidChars, offset, _a >> 8, _a);
  344. //if (dash) guidChars[offset++] = '-';
  345. //offset = HexsToChars(guidChars, offset, _b >> 8, _b);
  346. //if (dash) guidChars[offset++] = '-';
  347. //offset = HexsToChars(guidChars, offset, _c >> 8, _c);
  348. //if (dash) guidChars[offset++] = '-';
  349. //offset = HexsToChars(guidChars, offset, _d, _e);
  350. //if (dash) guidChars[offset++] = '-';
  351. //offset = HexsToChars(guidChars, offset, _f, _g);
  352. //offset = HexsToChars(guidChars, offset, _h, _i);
  353. //offset = HexsToChars(guidChars, offset, _j, _k);
  354.  
  355. #endregion
  356.  
  357. if (isComb)
  358. {
  359. offset = HexsToChars(guidChars, offset, m_value[10], m_value[11]);
  360. offset = HexsToChars(guidChars, offset, m_value[12], m_value[13]);
  361. offset = HexsToChars(guidChars, offset, m_value[14], m_value[15]);
  362. if (dash) { guidChars[offset++] = '-'; }
  363. offset = HexsToChars(guidChars, offset, m_value[8], m_value[9]);
  364. if (dash) { guidChars[offset++] = '-'; }
  365. offset = HexsToChars(guidChars, offset, m_value[6], m_value[7]);
  366. if (dash) { guidChars[offset++] = '-'; }
  367. offset = HexsToChars(guidChars, offset, m_value[4], m_value[5]);
  368. if (dash) { guidChars[offset++] = '-'; }
  369. offset = HexsToChars(guidChars, offset, m_value[0], m_value[1]);
  370. offset = HexsToChars(guidChars, offset, m_value[2], m_value[3]);
  371. }
  372. else
  373. {
  374. offset = HexsToChars(guidChars, offset, m_value[3], m_value[2]);
  375. offset = HexsToChars(guidChars, offset, m_value[1], m_value[0]);
  376. if (dash) { guidChars[offset++] = '-'; }
  377. offset = HexsToChars(guidChars, offset, m_value[5], m_value[4]);
  378. if (dash) { guidChars[offset++] = '-'; }
  379. offset = HexsToChars(guidChars, offset, m_value[7], m_value[6]);
  380. if (dash) { guidChars[offset++] = '-'; }
  381. offset = HexsToChars(guidChars, offset, m_value[8], m_value[9]);
  382. if (dash) { guidChars[offset++] = '-'; }
  383. offset = HexsToChars(guidChars, offset, m_value[10], m_value[11]);
  384. offset = HexsToChars(guidChars, offset, m_value[12], m_value[13]);
  385. offset = HexsToChars(guidChars, offset, m_value[14], m_value[15]);
  386. }
  387.  
  388. return new String(guidChars, 0, strLength);
  389. }
  390.  
  391. private static Int32 HexsToChars(Char[] guidChars, Int32 offset, Int32 a, Int32 b)
  392. {
  393. guidChars[offset++] = HexToChar(a >> 4);
  394. guidChars[offset++] = HexToChar(a);
  395. guidChars[offset++] = HexToChar(b >> 4);
  396. guidChars[offset++] = HexToChar(b);
  397. return offset;
  398. }
  399.  
  400. private static Char HexToChar(Int32 a)
  401. {
  402. a = a & 0xf;
  403. return (Char)((a > 9) ? a - 10 + 0x61 : a + 0x30);
  404. }
  405.  
  406. #endregion
  407.  
  408. #endregion
  409.  
  410. #region -- 静态方法 --
  411.  
  412. private static readonly DateTime _CombBaseDate = new DateTime(1900, 1, 1);
  413. private static Int32 _LastDays; // 天数
  414. private static Int32 _LastTenthMilliseconds; // 单位:1/10 毫秒
  415. private static readonly Int32 _MaxTenthMilliseconds = 863999999;
  416.  
  417. #region - NewComb -
  418.  
  419. /// <summary>初始化 CombGuid 结构的新实例。</summary>
  420. /// <returns>一个新的 CombGuid 对象。</returns>
  421. public static CombGuid NewComb()
  422. {
  423. var guidArray = Guid.NewGuid().ToByteArray();
  424.  
  425. var now = DateTime.Now;
  426.  
  427. // Get the days and milliseconds which will be used to build the Byte String
  428. var days = new TimeSpan(now.Ticks - _CombBaseDate.Ticks).Days;
  429. var tenthMilliseconds = (Int32)(now.TimeOfDay.TotalMilliseconds * 10D);
  430. var lastDays = _LastDays;
  431. var lastTenthMilliseconds = _LastTenthMilliseconds;
  432. if (days > lastDays)
  433. {
  434. Interlocked.CompareExchange(ref _LastDays, days, lastDays);
  435. Interlocked.CompareExchange(ref _LastTenthMilliseconds, tenthMilliseconds, lastTenthMilliseconds);
  436. }
  437. else
  438. {
  439. if (tenthMilliseconds > lastTenthMilliseconds)
  440. {
  441. Interlocked.CompareExchange(ref _LastTenthMilliseconds, tenthMilliseconds, lastTenthMilliseconds);
  442. }
  443. else
  444. {
  445. if (_LastTenthMilliseconds < Int32.MaxValue) { Interlocked.Increment(ref _LastTenthMilliseconds); }
  446. tenthMilliseconds = _LastTenthMilliseconds;
  447. }
  448. }
  449. // Convert to a Byte array
  450. var daysArray = BitConverter.GetBytes(days);
  451. var msecsArray = BitConverter.GetBytes(tenthMilliseconds);
  452.  
  453. // Reverse the bytes to match SQL Servers ordering
  454. Array.Reverse(daysArray);
  455. Array.Reverse(msecsArray);
  456.  
  457. // Copy the bytes into the guid
  458. Array.Copy(daysArray, daysArray.Length - 2, guidArray, guidArray.Length - 6, 2);
  459. //Array.Copy(msecsArray, msecsArray.Length - 4, guidArray, guidArray.Length - 4, 4);
  460. Array.Copy(msecsArray, 0, guidArray, guidArray.Length - 4, 4);
  461.  
  462. return new CombGuid(guidArray, true);
  463. }
  464.  
  465. #endregion
  466.  
  467. #region - Parse -
  468.  
  469. /// <summary>将 CombGuid 的字符串表示形式转换为等效的 CombGuid 结构。</summary>
  470. /// <param name="s">包含下面任一格式的 CombGuid 的字符串(“d”表示忽略大小写的十六进制数字):
  471. /// <para>32 个连续的数字 dddddddddddddddddddddddddddddddd </para>
  472. /// <para>- 或 - </para>
  473. /// <para>12 和 4、4、4、8 位数字的分组,各组之间有连线符,dddddddddddd-dddd-dddd-dddd-dddddddd</para>
  474. /// </param>
  475. /// <returns></returns>
  476. public static CombGuid Parse(String s)
  477. {
  478. if (_NullString == s)
  479. {
  480. return CombGuid.Null;
  481. }
  482. else
  483. {
  484. return new CombGuid(s);
  485. }
  486. }
  487.  
  488. #endregion
  489.  
  490. #region - TryParse -
  491.  
  492. /// <summary>将 CombGuid 的字符串表示形式转换为等效的 CombGuid 结构。</summary>
  493. /// <param name="comb">包含下面任一格式的 CombGuid 的字符串(“d”表示忽略大小写的十六进制数字):
  494. /// <para>32 个连续的数字 dddddddddddddddddddddddddddddddd </para>
  495. /// <para>- 或 - </para>
  496. /// <para>12 和 4、4、4、8 位数字的分组,各组之间有连线符,dddddddddddd-dddd-dddd-dddd-dddddddd</para>
  497. /// </param>
  498. /// <param name="result">将包含已分析的值的结构。 如果此方法返回 true,result 包含有效的 CombGuid。 如果此方法返回 false,result 等于 CombGuid.Null。</param>
  499. /// <returns></returns>
  500. public static Boolean TryParse(String comb, out CombGuid result)
  501. {
  502. ValidationHelper.ArgumentNullOrEmpty(comb, "comb");
  503.  
  504. Int32 a; Int16 b, c; Byte[] d;
  505. if (new GuidParser(comb).TryParse(out a, out b, out c, out d))
  506. {
  507. result = new CombGuid(a, b, c, d);
  508. return true;
  509. }
  510. result = Null;
  511. return false;
  512. }
  513.  
  514. /// <summary>将 CombGuid 的字符串表示形式转换为等效的 CombGuid 结构。</summary>
  515. /// <param name="value">Guid结构、CombGuid结构、16 元素字节数组 或 包含下面任一格式的 CombGuid 的字符串(“d”表示忽略大小写的十六进制数字):
  516. /// <para>32 个连续的数字 dddddddddddddddddddddddddddddddd </para>
  517. /// <para>- 或 - </para>
  518. /// <para>12 和 4、4、4、8 位数字的分组,各组之间有连线符,dddddddddddd-dddd-dddd-dddd-dddddddd</para>
  519. /// </param>
  520. /// <param name="result">将包含已分析的值的结构。 如果此方法返回 true,result 包含有效的 CombGuid。 如果此方法返回 false,result 等于 CombGuid.Null。</param>
  521. /// <returns></returns>
  522. public static Boolean TryParse(Object value, out CombGuid result)
  523. {
  524. ValidationHelper.ArgumentNull(value, "comb");
  525.  
  526. var type = value.GetType();
  527. if (type == typeof(String))
  528. {
  529. return TryParse(value as String, out result);
  530. }
  531. else if (type == typeof(Byte[]))
  532. {
  533. var bs = value as Byte[];
  534. if (bs.Length == _SizeOfGuid)
  535. {
  536. result = new CombGuid(bs);
  537. return true;
  538. }
  539. }
  540. else if (type == typeof(CombGuid))
  541. {
  542. result = (CombGuid)value;
  543. return true;
  544. }
  545. else if (type == typeof(Guid))
  546. {
  547. result = (CombGuid)value;
  548. return true;
  549. }
  550.  
  551. result = Null;
  552. return false;
  553. }
  554.  
  555. #endregion
  556.  
  557. #endregion
  558.  
  559. #region -- 类型转换 --
  560.  
  561. /// <summary>将此 Guid 结构转换为 CombGuid</summary>
  562. /// <param name="x">一个 Guid</param>
  563. /// <returns></returns>
  564. public static implicit operator CombGuid(Guid x)
  565. {
  566. return new CombGuid(x);
  567. }
  568.  
  569. /// <summary>将此 CombGuid 结构转换为 Guid</summary>
  570. /// <param name="x">一个 CombGuid</param>
  571. /// <returns></returns>
  572. public static explicit operator Guid(CombGuid x)
  573. {
  574. return x.Value;
  575. }
  576.  
  577. #endregion
  578.  
  579. #region -- 重载运算符 --
  580.  
  581. /// <summary>Comparison operators</summary>
  582. /// <param name="x"></param>
  583. /// <param name="y"></param>
  584. /// <returns></returns>
  585. private static CombGuidComparison Compare(CombGuid x, CombGuid y)
  586. {
  587. // Swap to the correct order to be compared
  588. for (Int32 i = 0; i < _SizeOfGuid; i++)
  589. {
  590. Byte b1, b2;
  591.  
  592. b1 = x.m_value[_GuidComparisonOrders[i]];
  593. b2 = y.m_value[_GuidComparisonOrders[i]];
  594. if (b1 != b2)
  595. {
  596. return (b1 < b2) ? CombGuidComparison.LT : CombGuidComparison.GT;
  597. }
  598. }
  599. return CombGuidComparison.EQ;
  600. }
  601.  
  602. /// <summary>对两个 CombGuid 结构执行逻辑比较,以确定它们是否相等</summary>
  603. /// <param name="x">一个 CombGuid 结构</param>
  604. /// <param name="y">一个 CombGuid 结构</param>
  605. /// <returns>它在两个 CombGuid 结构相等时为 True,在两个实例不等时为 False。</returns>
  606. public static Boolean operator ==(CombGuid x, CombGuid y)
  607. {
  608. if (x.IsNull || y.IsNull)
  609. {
  610. return (x.IsNull && y.IsNull);
  611. }
  612. else
  613. {
  614. return Compare(x, y) == CombGuidComparison.EQ;
  615. }
  616. }
  617.  
  618. /// <summary>对两个 CombGuid 结构执行逻辑比较,以确定它们是否不相等。</summary>
  619. /// <param name="x">一个 CombGuid 结构</param>
  620. /// <param name="y">一个 CombGuid 结构</param>
  621. /// <returns>它在两个 CombGuid 结构不等时为 True,在两个实例相等时为 False。</returns>
  622. public static Boolean operator !=(CombGuid x, CombGuid y)
  623. {
  624. return !(x == y);
  625. }
  626.  
  627. /// <summary>对 CombGuid 结构的两个实例进行比较,以确定第一个实例是否小于第二个实例。</summary>
  628. /// <param name="x">一个 CombGuid 结构</param>
  629. /// <param name="y">一个 CombGuid 结构</param>
  630. /// <returns>如果第一个实例小于第二个实例,则它为 True。 否则为 False。</returns>
  631. public static Boolean operator <(CombGuid x, CombGuid y)
  632. {
  633. if (x.IsNull || y.IsNull)
  634. {
  635. return (x.IsNull && !y.IsNull);
  636. }
  637. else
  638. {
  639. return Compare(x, y) == CombGuidComparison.LT;
  640. }
  641. }
  642.  
  643. /// <summary>对 CombGuid 结构的两个实例进行比较,以确定第一个实例是否大于第二个实例。</summary>
  644. /// <param name="x">一个 CombGuid 结构</param>
  645. /// <param name="y">一个 CombGuid 结构</param>
  646. /// <returns>如果第一个实例大于第二个实例,则它为 True。 否则为 False。</returns>
  647. public static Boolean operator >(CombGuid x, CombGuid y)
  648. {
  649. if (x.IsNull || y.IsNull)
  650. {
  651. return (!x.IsNull && y.IsNull);
  652. }
  653. else
  654. {
  655. return Compare(x, y) == CombGuidComparison.GT;
  656. }
  657. }
  658.  
  659. /// <summary>对 CombGuid 结构的两个实例进行比较,以确定第一个实例是否小于或等于第二个实例。</summary>
  660. /// <param name="x">一个 CombGuid 结构</param>
  661. /// <param name="y">一个 CombGuid 结构</param>
  662. /// <returns>如果第一个实例小于或等于第二个实例,则它为 True。 否则为 False。</returns>
  663. public static Boolean operator <=(CombGuid x, CombGuid y)
  664. {
  665. if (x.IsNull || y.IsNull)
  666. {
  667. return x.IsNull;
  668. }
  669. else
  670. {
  671. var cmp = Compare(x, y);
  672. return cmp == CombGuidComparison.LT || cmp == CombGuidComparison.EQ;
  673. }
  674. }
  675.  
  676. /// <summary>对 CombGuid 结构的两个实例进行比较,以确定第一个实例是否大于或等于第二个实例。</summary>
  677. /// <param name="x">一个 CombGuid 结构</param>
  678. /// <param name="y">一个 CombGuid 结构</param>
  679. /// <returns>如果第一个实例大于或等于第二个实例,则为 True。 否则为 False。</returns>
  680. public static Boolean operator >=(CombGuid x, CombGuid y)
  681. {
  682. if (x.IsNull || y.IsNull)
  683. {
  684. return y.IsNull;
  685. }
  686. else
  687. {
  688. var cmp = Compare(x, y);
  689. return cmp == CombGuidComparison.GT || cmp == CombGuidComparison.EQ;
  690. }
  691. }
  692.  
  693. /// <summary>对两个 CombGuid 结构执行逻辑比较,以确定它们是否相等</summary>
  694. /// <param name="x">一个 CombGuid 结构</param>
  695. /// <param name="y">一个 CombGuid 结构</param>
  696. /// <returns>它在两个 CombGuid 结构相等时为 True,在两个实例不等时为 False。</returns>
  697. public static Boolean Equals(CombGuid x, CombGuid y)
  698. {
  699. return (x == y);
  700. }
  701.  
  702. /// <summary>对两个 CombGuid 结构执行逻辑比较,以确定它们是否不相等。</summary>
  703. /// <param name="x">一个 CombGuid 结构</param>
  704. /// <param name="y">一个 CombGuid 结构</param>
  705. /// <returns>它在两个 CombGuid 结构不等时为 True,在两个实例相等时为 False。</returns>
  706. public static Boolean NotEquals(CombGuid x, CombGuid y)
  707. {
  708. return (x != y);
  709. }
  710.  
  711. /// <summary>对 CombGuid 结构的两个实例进行比较,以确定第一个实例是否小于第二个实例。</summary>
  712. /// <param name="x">一个 CombGuid 结构</param>
  713. /// <param name="y">一个 CombGuid 结构</param>
  714. /// <returns>如果第一个实例小于第二个实例,则它为 True。 否则为 False。</returns>
  715. public static Boolean LessThan(CombGuid x, CombGuid y)
  716. {
  717. return (x < y);
  718. }
  719.  
  720. /// <summary>对 CombGuid 结构的两个实例进行比较,以确定第一个实例是否大于第二个实例。</summary>
  721. /// <param name="x">一个 CombGuid 结构</param>
  722. /// <param name="y">一个 CombGuid 结构</param>
  723. /// <returns>如果第一个实例大于第二个实例,则它为 True。 否则为 False。</returns>
  724. public static Boolean GreaterThan(CombGuid x, CombGuid y)
  725. {
  726. return (x > y);
  727. }
  728.  
  729. /// <summary>对 CombGuid 结构的两个实例进行比较,以确定第一个实例是否小于或等于第二个实例。</summary>
  730. /// <param name="x">一个 CombGuid 结构</param>
  731. /// <param name="y">一个 CombGuid 结构</param>
  732. /// <returns>如果第一个实例小于或等于第二个实例,则它为 True。 否则为 False。</returns>
  733. public static Boolean LessThanOrEqual(CombGuid x, CombGuid y)
  734. {
  735. return (x <= y);
  736. }
  737.  
  738. /// <summary>对 CombGuid 结构的两个实例进行比较,以确定第一个实例是否大于或等于第二个实例。</summary>
  739. /// <param name="x">一个 CombGuid 结构</param>
  740. /// <param name="y">一个 CombGuid 结构</param>
  741. /// <returns>如果第一个实例大于或等于第二个实例,则为 True。 否则为 False。</returns>
  742. public static Boolean GreaterThanOrEqual(CombGuid x, CombGuid y)
  743. {
  744. return (x >= y);
  745. }
  746.  
  747. #endregion
  748.  
  749. #region -- CombGuid 相等 --
  750.  
  751. /// <summary>已重载,判断两个 CombGuid 结构是否相等</summary>
  752. /// <param name="value"></param>
  753. /// <returns></returns>
  754. public override Boolean Equals(Object value)
  755. {
  756. if ((value.GetType() != typeof(CombGuid))) { return false; }
  757.  
  758. return this == (CombGuid)value;
  759. }
  760.  
  761. /// <summary>判断两个 CombGuid 结构是否相等</summary>
  762. /// <param name="value"></param>
  763. /// <returns></returns>
  764. public Boolean Equals(CombGuid value)
  765. {
  766. return this == value;
  767. }
  768.  
  769. /// <summary>已重载,获取该 CombGuid 结构的哈希代码</summary>
  770. /// <returns></returns>
  771. public override Int32 GetHashCode()
  772. {
  773. return IsNull ? 0 : Value.GetHashCode();
  774. }
  775.  
  776. #endregion
  777.  
  778. #region -- INullable 成员 --
  779.  
  780. /// <summary>获取一个布尔值,该值指示此 CombGuid 结构是否为 null。</summary>
  781. public Boolean IsNull
  782. {
  783. get { return (m_value == null); }
  784. }
  785.  
  786. #endregion
  787.  
  788. #region -- IComparable 成员 --
  789.  
  790. /// <summary>将此 CombGuid 结构与所提供的对象进行比较,并返回其相对值的指示。 不仅仅是比较最后 6 个字节,但会将最后 6 个字节视为比较中最重要的字节。</summary>
  791. /// <param name="value">要比较的对象</param>
  792. /// <returns>一个有符号的数字,它指示该实例和对象的相对值。
  793. /// <para>小于零,此实例小于对象。</para>
  794. /// <para>零,此实例等于对象。</para>
  795. /// <para>大于零,此实例大于对象;或对象是 null 引用 (Nothing)</para>
  796. /// </returns>
  797. public Int32 CompareTo(Object value)
  798. {
  799. if (value.GetType() == typeof(CombGuid))
  800. {
  801. var combGuid = (CombGuid)value;
  802.  
  803. return CompareTo(combGuid);
  804. }
  805. throw new ArgumentException("value 类型不是 CombGuid");
  806. }
  807.  
  808. /// <summary>将此 CombGuid 结构与所提供的 CombGuid 结构进行比较,并返回其相对值的指示。 不仅仅是比较最后 6 个字节,但会将最后 6 个字节视为比较中最重要的字节。</summary>
  809. /// <param name="value">要比较的 CombGuid 结构</param>
  810. /// <returns>一个有符号的数字,它指示该实例和对象的相对值。
  811. /// <para>小于零,此实例小于对象。</para>
  812. /// <para>零,此实例等于对象。</para>
  813. /// <para>大于零,此实例大于对象;或对象是 null 引用 (Nothing)</para>
  814. /// </returns>
  815. public Int32 CompareTo(CombGuid value)
  816. {
  817. // If both Null, consider them equal.
  818. // Otherwise, Null is less than anything.
  819. if (IsNull)
  820. {
  821. return value.IsNull ? 0 : -1;
  822. }
  823. else if (value.IsNull)
  824. {
  825. return 1;
  826. }
  827.  
  828. //if (this < value) { return -1; }
  829. //if (this > value) { return 1; }
  830. //return 0;
  831. var cmp = Compare(this, value);
  832. switch (cmp)
  833. {
  834. case CombGuidComparison.LT:
  835. return -1;
  836.  
  837. case CombGuidComparison.GT:
  838. return 1;
  839.  
  840. case CombGuidComparison.EQ:
  841. default:
  842. return 0;
  843. }
  844. }
  845.  
  846. #endregion
  847.  
  848. #region -- IXmlSerializable 成员 --
  849.  
  850. XmlSchema IXmlSerializable.GetSchema()
  851. {
  852. return null;
  853. }
  854.  
  855. /// <summary>从 CombGuid 结构的 XML 表示形式生成该对象</summary>
  856. /// <param name="reader"></param>
  857. void IXmlSerializable.ReadXml(XmlReader reader)
  858. {
  859. var isNull = reader.GetAttribute(_NullString, XmlSchema.InstanceNamespace);
  860. if (isNull != null && XmlConvert.ToBoolean(isNull))
  861. {
  862. // VSTFDevDiv# 479603 - SqlTypes read null value infinitely and never read the next value. Fix - Read the next value.
  863. reader.ReadElementString();
  864. m_value = null;
  865. }
  866. else
  867. {
  868. m_value = new Guid(reader.ReadElementString()).ToByteArray();
  869. }
  870. }
  871.  
  872. /// <summary>将该 CombGuid 结构转换为其 XML 表示形式</summary>
  873. /// <param name="writer"></param>
  874. void IXmlSerializable.WriteXml(XmlWriter writer)
  875. {
  876. if (IsNull)
  877. {
  878. writer.WriteAttributeString("xsi", _NullString, XmlSchema.InstanceNamespace, "true");
  879. }
  880. else
  881. {
  882. writer.WriteString(XmlConvert.ToString(new Guid(m_value)));
  883. }
  884. }
  885.  
  886. public static XmlQualifiedName GetXsdType(XmlSchemaSet schemaSet)
  887. {
  888. return new XmlQualifiedName("String", XmlSchema.Namespace);
  889. }
  890.  
  891. #endregion
  892.  
  893. #region -- struct GuidParser --
  894.  
  895. private struct GuidParser
  896. {
  897. private String _src;
  898. private Int32 _length;
  899. private Int32 _cur;
  900.  
  901. internal GuidParser(String src)
  902. {
  903. _src = src.Trim();
  904. _cur = 0;
  905. _length = _src.Length;
  906. }
  907.  
  908. private void Reset()
  909. {
  910. _cur = 0;
  911. _length = _src.Length;
  912. }
  913.  
  914. private Boolean Eof
  915. {
  916. get { return _cur >= _length; }
  917. }
  918.  
  919. internal Boolean TryParse(out Int32 a, out Int16 b, out Int16 c, out Byte[] d)
  920. {
  921. var hasHyphen = _length == 36;
  922.  
  923. a = 0; b = 0; c = 0; d = null;
  924. UInt64 _a, _b, _c;
  925.  
  926. if (!ParseHex(8, hasHyphen, out _a)) { return false; }
  927.  
  928. if (hasHyphen && !ParseChar('-')) { return false; }
  929.  
  930. if (!ParseHex(4, hasHyphen, out _b)) { return false; }
  931.  
  932. if (hasHyphen && !ParseChar('-')) { return false; }
  933.  
  934. if (!ParseHex(4, hasHyphen, out _c)) { return false; }
  935.  
  936. if (hasHyphen && !ParseChar('-')) { return false; }
  937.  
  938. var _d = new Byte[8];
  939. for (Int32 i = 0; i < _d.Length; i++)
  940. {
  941. UInt64 dd;
  942. if (!ParseHex(2, hasHyphen, out dd)) { return false; }
  943.  
  944. if (i == 1 && hasHyphen && !ParseChar('-')) { return false; }
  945.  
  946. _d[i] = (Byte)dd;
  947. }
  948.  
  949. if (!Eof) { return false; }
  950.  
  951. a = (Int32)_a;
  952. b = (Int16)_b;
  953. c = (Int16)_c;
  954. d = _d;
  955. return true;
  956. }
  957.  
  958. private Boolean ParseChar(Char c)
  959. {
  960. if (!Eof && _src[_GuidParseOrders36[_cur]] == c)
  961. {
  962. _cur++;
  963. return true;
  964. }
  965.  
  966. return false;
  967. }
  968.  
  969. private Boolean ParseHex(Int32 length, Boolean hasHyphen, out UInt64 res) //Boolean strict
  970. {
  971. res = 0;
  972.  
  973. for (Int32 i = 0; i < length; i++)
  974. {
  975. //if (Eof)
  976. // return !(strict && (i + 1 != length));
  977. if (Eof) { return !((i + 1 != length)); }
  978.  
  979. var c = hasHyphen ? _src[_GuidParseOrders36[_cur]] : _src[_GuidParseOrders32[_cur]];
  980. if (Char.IsDigit(c))
  981. {
  982. res = res * 16 + c - '0';
  983. _cur++;
  984. continue;
  985. }
  986.  
  987. if (c >= 'a' && c <= 'f')
  988. {
  989. res = res * 16 + c - 'a' + 10;
  990. _cur++;
  991. continue;
  992. }
  993.  
  994. if (c >= 'A' && c <= 'F')
  995. {
  996. res = res * 16 + c - 'A' + 10;
  997. _cur++;
  998. continue;
  999. }
  1000.  
  1001. //if (!strict)
  1002. // return true;
  1003.  
  1004. return false; //!(strict && (i + 1 != length));
  1005. }
  1006.  
  1007. return true;
  1008. }
  1009. }
  1010.  
  1011. #endregion
  1012.  
  1013. #region -- enum CombGuidComparison --
  1014.  
  1015. private enum CombGuidComparison
  1016. {
  1017. LT,
  1018. EQ,
  1019. GT
  1020. }
  1021.  
  1022. #endregion
  1023. }
  1024.  
  1025. /// <summary>CombGuid 结构格式化字符串方式</summary>
  1026. public enum CombGuidFormatStringType
  1027. {
  1028. /// <summary>Guid 格式字符串,用一系列指定格式的小写十六进制位表示,由连字符("-")分隔的 32 位数字,这些十六进制位分别以 8 个、4 个、4 个、4 个和 12 个位为一组并由连字符分隔开。</summary>
  1029. Guid,
  1030.  
  1031. /// <summary>Guid 格式字符串,用一系列指定格式的小写十六进制位表示,32 位数字,这些十六进制位分别以 8 个、4 个、4 个、4 个和 12 个位为一组合并而成。</summary>
  1032. Guid32Digits,
  1033.  
  1034. /// <summary>CombGuid 格式字符串,用一系列指定格式的小写十六进制位表示,由连字符("-")分隔的 32 位数字,这些十六进制位分别以 12 个和 4 个、4 个、4 个、8 个位为一组并由连字符分隔开。</summary>
  1035. Comb,
  1036.  
  1037. /// <summary>CombGuid 格式字符串,用一系列指定格式的小写十六进制位表示,32 位数字,这些十六进制位分别以 12 个和 4 个、4 个、4 个、8 个位为一组合并而成。</summary>
  1038. Comb32Digits
  1039. }
  1040. }

可排序的 COMB 类型 GUID的更多相关文章

  1. EasyUI datagird 排序 按数字类型的问题

    easyui datagird 默认显示的数据都是字符, 对要数字列进行排序规则,需要自定义排序规则如果按字符排序 27竟然小于4 这不是我们想要的.解决方案 <table id='grid'c ...

  2. java编程排序之自定义类型的集合,按业务需求排序

    自定义引用类型放入集合中,按实际业务需求进行排序的两种思路 第一种思路: (1)自定义实体类实现java.lang.Comparable接口,重写public int compareTo(Object ...

  3. ECSHOP任意页面显示指定分类、数量、排序的任意类型文章,包括只显示置顶or普通的文章

    1.在需要使用此功能的PHP页面里最后的?>前面添加以下代码,现在以article.php为例子 /** jinmozhe 专业ECSHOP二次开发 * 获得指定分类ID.文章类型.指定数量.排 ...

  4. 根据SQL Server排序规则创建顺序GUID

    public static class GuidUtil { , , , , , , DateTimeKind.Utc).Ticks / 10000L; /// <summary> /// ...

  5. [转]Visual Studio 项目类型 GUID 清单

    转自:https://www.codeproject.com/Reference/720512/List-of-Visual-Studio-Project-Type-GUIDs Complete li ...

  6. 事务环境下的CombGuid

    一直使用osharp,osharp3使用的是combguid,代码如下 /// <summary> /// 返回Guid用于数据库操作,特定的时间代码可以提高检索效率 /// </s ...

  7. java利用自定义类型对树形数据类型进行排序

    前言 为什么集合在存自定义类型时需要重写equals和hashCode? 1.先说List集合 List集合在存数据时是可以重复的但是 当我们需要判断一个对象是否在集合中存在时这样就有问题了! 因为我 ...

  8. Go语言入门篇-基本类型排序和 slice 排序

    参见博客:https://blog.csdn.net/u010983881/article/details/52460998 package main import ( "sort" ...

  9. C# 泛型集合的自定义类型排序

    一.泛型集合List<T>排序 经sort方法之后,采用了升序的方式进行排列的. List<int> list = new List<int>() { 2, 4, ...

随机推荐

  1. java软件设计模式——单例设计模式中的【饿汉式】与 【懒汉式】示例

    以下为单例设计模式中的两种经典模式的代码示意: 单例设计模式(spring框架IOC,默认创建的对象都是单例的): 饿汉式: public class SingleClass { private Si ...

  2. PHP环境基础配置

    域名访问设置(本地局域网) 用记事本打开 127.0.0.1是本地回环地址 配置完后 通过在本地浏览器输入www.0705.com就可以访问本地站点了 Wamp集成环境多站点配置 配置条件: 一个服务 ...

  3. scp 远程复制

    1. 上传本地文件到远程机器指定目录 命令: scp /opt/soft/nginx-0.5.38.tar.gz root@192.168.120.204:/opt/soft/scptest 上传本地 ...

  4. HTTPS的页面发送不了HTTP请求?——关于混合内容

    我们都知道HTTPS的页面是发送不了HTTP请求的,那么是什么原因导致HTTPS页面不能发送HTTP请求呢?如果有发送的需求,怎么样才能发送?最近刚好遇到了这个问题,而且搜了半天没搜到靠谱的答案,所以 ...

  5. 来谈谈 WebAssembly 是个啥?为何说它会影响每一个 Web 开发者?

    作者:link 原文:What is WebAssembly and why it affects web developers! 你听说过WebAssembly吗?这是由Google, Micros ...

  6. PropertyGrid 重难点总结

    PropertyGrid的界面组成与不同部分的名称如下图所示. 本博文不算是自己写作的,只是将PropertyGrid中的几项十分有用的功能的应用方面的文字进行一下总结,希望以后大家对Property ...

  7. jq循环方法

    jq在前台使用很广泛,其中不可避免会用到循环,for循环可以,但有时不方便,下边举两个jq循环: 第一个: $.each(数组或对象,function(index,item){ //循环的逻辑代码 } ...

  8. python web框架简介Bottle Flask Tornado

    Bottle Bottle是一个快速.简洁.轻量级的基于WSIG的微型Web框架,此框架只由一个 .py 文件,除了Python的标准库外,其不依赖任何其他模块. ? 1 2 3 4 pip inst ...

  9. redis 开发与运维 学习心得1

    主要是命令相关 第一章 初识Redis 1.redis是基于键值对的NoSQL. 2.redis的值可以是 string, hash, list, set, zset, bitmaps, hyperl ...

  10. tree的所有节点都勾选上或者取消勾选

    还有一个功能,就是让tree的所有节点都勾选上或者取消勾选,在api中找了一下有一个方法: check target 选中指定节点. 那我们只能是选中根节点后,实现全选. getRoot none 获 ...