VersionNumber.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. using System;
  2. using System.Runtime.Serialization;
  3. namespace Masuit.Tools.Models;
  4. /// <summary>
  5. /// 版本号
  6. /// </summary>
  7. [DataContract]
  8. public sealed record VersionNumber : IComparable, IComparable<VersionNumber>
  9. {
  10. /// <summary>
  11. /// 版本号
  12. /// </summary>
  13. /// <param name="major">主版本号</param>
  14. /// <param name="minor">子版本号</param>
  15. /// <param name="build">编译版本号</param>
  16. /// <param name="revision">修订版本号</param>
  17. public VersionNumber(uint major, uint minor, uint build, uint revision) : this(major, minor, build)
  18. {
  19. Revision = revision;
  20. }
  21. /// <summary>
  22. /// 版本号
  23. /// </summary>
  24. /// <param name="major">主版本号</param>
  25. /// <param name="minor">子版本号</param>
  26. /// <param name="build">编译版本号</param>
  27. public VersionNumber(uint major, uint minor, uint build) : this(major, minor)
  28. {
  29. Build = build;
  30. }
  31. /// <summary>
  32. /// 版本号
  33. /// </summary>
  34. /// <param name="major">主版本号</param>
  35. /// <param name="minor">子版本号</param>
  36. public VersionNumber(uint major, uint minor)
  37. {
  38. Major = major;
  39. Minor = minor;
  40. }
  41. /// <summary>
  42. /// 版本号
  43. /// </summary>
  44. public VersionNumber(string version)
  45. {
  46. if (Version.TryParse(version, out var v))
  47. {
  48. Major = (uint)Math.Max(0, v.Major);
  49. Minor = (uint)Math.Max(0, v.Minor);
  50. Build = (uint)Math.Max(0, v.Build);
  51. Revision = (uint)Math.Max(0, v.Revision);
  52. }
  53. }
  54. /// <summary>
  55. /// 版本号
  56. /// </summary>
  57. public VersionNumber(double version)
  58. {
  59. Major = (uint)version;
  60. Minor = (uint)((version - Major) * 10);
  61. }
  62. /// <summary>
  63. /// 字符串转换成版本号
  64. /// </summary>
  65. /// <param name="v"></param>
  66. /// <returns></returns>
  67. public static VersionNumber Parse(string v)
  68. {
  69. return new VersionNumber(v);
  70. }
  71. /// <summary>
  72. /// 字符串尝试转换成版本号
  73. /// </summary>
  74. /// <param name="v"></param>
  75. /// <param name="version"></param>
  76. /// <returns></returns>
  77. public static bool TryParse(string v, out VersionNumber version)
  78. {
  79. if (Version.TryParse(v, out var ver))
  80. {
  81. version = new VersionNumber((uint)Math.Max(0, ver.Major), (uint)Math.Max(0, ver.Minor), (uint)Math.Max(0, ver.Build), (uint)Math.Max(0, ver.Revision));
  82. return true;
  83. }
  84. version = null;
  85. return false;
  86. }
  87. /// <summary>
  88. /// 主版本号
  89. /// </summary>
  90. public uint Major { get; }
  91. /// <summary>
  92. /// 子版本号
  93. /// </summary>
  94. public uint Minor { get; }
  95. /// <summary>
  96. /// 编译版本号
  97. /// </summary>
  98. public uint Build { get; }
  99. /// <summary>
  100. /// 修订版本号
  101. /// </summary>
  102. public uint Revision { get; }
  103. public short MajorRevision => (short)(Revision >> 16);
  104. public short MinorRevision => (short)(Revision & 0xFFFF);
  105. public int CompareTo(object version)
  106. {
  107. if (version == null)
  108. {
  109. return 1;
  110. }
  111. if (version is VersionNumber v)
  112. {
  113. return CompareTo(v);
  114. }
  115. throw new ArgumentException(nameof(version));
  116. }
  117. public int CompareTo(VersionNumber value)
  118. {
  119. return ReferenceEquals(value, this) ? 0 : value is null ? 1 : Major != value.Major ? (Major > value.Major ? 1 : -1) : Minor != value.Minor ? (Minor > value.Minor ? 1 : -1) : Build != value.Build ? (Build > value.Build ? 1 : -1) : Revision != value.Revision ? (Revision > value.Revision ? 1 : -1) : 0;
  120. }
  121. public bool Equals(VersionNumber obj)
  122. {
  123. return ReferenceEquals(obj, this) || (!(obj is null) && Major == obj.Major && Minor == obj.Minor && Build == obj.Build && Revision == obj.Revision);
  124. }
  125. public override int GetHashCode()
  126. {
  127. uint accumulator = 0;
  128. accumulator |= (Major & 0x0000000F) << 28;
  129. accumulator |= (Minor & 0x000000FF) << 20;
  130. accumulator |= (Build & 0x000000FF) << 12;
  131. accumulator |= (Revision & 0x00000FFF);
  132. return (int)accumulator;
  133. }
  134. public override string ToString() => (Major + "." + Minor + "." + Build + "." + Revision).TrimEnd('.', '0');
  135. public static bool operator <(VersionNumber v1, VersionNumber v2)
  136. {
  137. if (v1 is null)
  138. {
  139. return v2 is not null;
  140. }
  141. return v1.CompareTo(v2) < 0;
  142. }
  143. public static bool operator <=(VersionNumber v1, VersionNumber v2)
  144. {
  145. if (v1 is null)
  146. {
  147. return true;
  148. }
  149. return v1.CompareTo(v2) <= 0;
  150. }
  151. public static bool operator >(VersionNumber v1, VersionNumber v2) => v2 < v1;
  152. public static bool operator >=(VersionNumber v1, VersionNumber v2) => v2 <= v1;
  153. public static VersionNumber operator +(VersionNumber v1, decimal v2)
  154. {
  155. int major = (int)v2;
  156. int minor = (int)((v2 - major) * 10);
  157. return new VersionNumber((uint)(v1.Major + major), (uint)(v1.Minor + minor), v1.Build, v1.Revision);
  158. }
  159. public static VersionNumber operator +(VersionNumber v1, double v2)
  160. {
  161. int major = (int)v2;
  162. int minor = (int)((v2 - major) * 10);
  163. return new VersionNumber((uint)(v1.Major + major), (uint)(v1.Minor + minor), v1.Build, v1.Revision);
  164. }
  165. public static VersionNumber operator +(VersionNumber v1, int v2)
  166. {
  167. return new VersionNumber((uint)(v1.Major + v2), v1.Minor, v1.Build, v1.Revision);
  168. }
  169. public static VersionNumber operator +(VersionNumber v1, VersionNumber v2)
  170. {
  171. return new VersionNumber(v1.Major + v2.Major, v1.Minor + v2.Minor, v1.Build + v2.Build, v1.Revision + v2.Revision);
  172. }
  173. /// <summary>
  174. ///
  175. /// </summary>
  176. /// <param name="v"></param>
  177. /// <returns></returns>
  178. public static implicit operator VersionNumber(string v)
  179. {
  180. return new VersionNumber(v);
  181. }
  182. /// <summary>
  183. ///
  184. /// </summary>
  185. /// <param name="v"></param>
  186. /// <returns></returns>
  187. public static implicit operator string(VersionNumber v)
  188. {
  189. return v.ToString();
  190. }
  191. }