DiscriminatedUnion.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. using System;
  2. using System.Runtime.InteropServices;
  3. namespace ProtoBuf
  4. {
  5. /// <summary>Represent multiple types as a union; this is used as part of OneOf -
  6. /// note that it is the caller's responsbility to only read/write the value as the same type</summary>
  7. public readonly partial struct DiscriminatedUnionObject
  8. {
  9. /// <summary>The value typed as Object</summary>
  10. public readonly object Object;
  11. /// <summary>Indicates whether the specified discriminator is assigned</summary>
  12. public bool Is(int discriminator) => Discriminator == discriminator;
  13. /// <summary>Create a new discriminated union value</summary>
  14. public DiscriminatedUnionObject(int discriminator, object value)
  15. {
  16. Discriminator = discriminator;
  17. Object = value;
  18. }
  19. /// <summary>Reset a value if the specified discriminator is assigned</summary>
  20. public static void Reset(ref DiscriminatedUnionObject value, int discriminator)
  21. {
  22. if (value.Discriminator == discriminator) value = default;
  23. }
  24. /// <summary>The discriminator value</summary>
  25. public int Discriminator { get; }
  26. }
  27. /// <summary>Represent multiple types as a union; this is used as part of OneOf -
  28. /// note that it is the caller's responsbility to only read/write the value as the same type</summary>
  29. [StructLayout(LayoutKind.Explicit)]
  30. public readonly partial struct DiscriminatedUnion64
  31. {
  32. #if !FEAT_SAFE
  33. unsafe static DiscriminatedUnion64()
  34. {
  35. if (sizeof(DateTime) > 8) throw new InvalidOperationException(nameof(DateTime) + " was unexpectedly too big for " + nameof(DiscriminatedUnion64));
  36. if (sizeof(TimeSpan) > 8) throw new InvalidOperationException(nameof(TimeSpan) + " was unexpectedly too big for " + nameof(DiscriminatedUnion64));
  37. }
  38. #endif
  39. [FieldOffset(0)] private readonly int _discriminator; // note that we can't pack further because Object needs x8 alignment/padding on x64
  40. /// <summary>The value typed as Int64</summary>
  41. [FieldOffset(8)] public readonly long Int64;
  42. /// <summary>The value typed as UInt64</summary>
  43. [FieldOffset(8)] public readonly ulong UInt64;
  44. /// <summary>The value typed as Int32</summary>
  45. [FieldOffset(8)] public readonly int Int32;
  46. /// <summary>The value typed as UInt32</summary>
  47. [FieldOffset(8)] public readonly uint UInt32;
  48. /// <summary>The value typed as Boolean</summary>
  49. [FieldOffset(8)] public readonly bool Boolean;
  50. /// <summary>The value typed as Single</summary>
  51. [FieldOffset(8)] public readonly float Single;
  52. /// <summary>The value typed as Double</summary>
  53. [FieldOffset(8)] public readonly double Double;
  54. /// <summary>The value typed as DateTime</summary>
  55. [FieldOffset(8)] public readonly DateTime DateTime;
  56. /// <summary>The value typed as TimeSpan</summary>
  57. [FieldOffset(8)] public readonly TimeSpan TimeSpan;
  58. private DiscriminatedUnion64(int discriminator) : this()
  59. {
  60. _discriminator = discriminator;
  61. }
  62. /// <summary>Indicates whether the specified discriminator is assigned</summary>
  63. public bool Is(int discriminator) => _discriminator == discriminator;
  64. /// <summary>Create a new discriminated union value</summary>
  65. public DiscriminatedUnion64(int discriminator, long value) : this(discriminator) { Int64 = value; }
  66. /// <summary>Create a new discriminated union value</summary>
  67. public DiscriminatedUnion64(int discriminator, int value) : this(discriminator) { Int32 = value; }
  68. /// <summary>Create a new discriminated union value</summary>
  69. public DiscriminatedUnion64(int discriminator, ulong value) : this(discriminator) { UInt64 = value; }
  70. /// <summary>Create a new discriminated union value</summary>
  71. public DiscriminatedUnion64(int discriminator, uint value) : this(discriminator) { UInt32 = value; }
  72. /// <summary>Create a new discriminated union value</summary>
  73. public DiscriminatedUnion64(int discriminator, float value) : this(discriminator) { Single = value; }
  74. /// <summary>Create a new discriminated union value</summary>
  75. public DiscriminatedUnion64(int discriminator, double value) : this(discriminator) { Double = value; }
  76. /// <summary>Create a new discriminated union value</summary>
  77. public DiscriminatedUnion64(int discriminator, bool value) : this(discriminator) { Boolean = value; }
  78. /// <summary>Create a new discriminated union value</summary>
  79. public DiscriminatedUnion64(int discriminator, DateTime? value) : this(value.HasValue ? discriminator: 0) { DateTime = value.GetValueOrDefault(); }
  80. /// <summary>Create a new discriminated union value</summary>
  81. public DiscriminatedUnion64(int discriminator, TimeSpan? value) : this(value.HasValue ? discriminator : 0) { TimeSpan = value.GetValueOrDefault(); }
  82. /// <summary>Reset a value if the specified discriminator is assigned</summary>
  83. public static void Reset(ref DiscriminatedUnion64 value, int discriminator)
  84. {
  85. if (value.Discriminator == discriminator) value = default;
  86. }
  87. /// <summary>The discriminator value</summary>
  88. public int Discriminator => _discriminator;
  89. }
  90. /// <summary>Represent multiple types as a union; this is used as part of OneOf -
  91. /// note that it is the caller's responsbility to only read/write the value as the same type</summary>
  92. [StructLayout(LayoutKind.Explicit)]
  93. public readonly partial struct DiscriminatedUnion128Object
  94. {
  95. #if !FEAT_SAFE
  96. unsafe static DiscriminatedUnion128Object()
  97. {
  98. if (sizeof(DateTime) > 16) throw new InvalidOperationException(nameof(DateTime) + " was unexpectedly too big for " + nameof(DiscriminatedUnion128Object));
  99. if (sizeof(TimeSpan) > 16) throw new InvalidOperationException(nameof(TimeSpan) + " was unexpectedly too big for " + nameof(DiscriminatedUnion128Object));
  100. if (sizeof(Guid) > 16) throw new InvalidOperationException(nameof(Guid) + " was unexpectedly too big for " + nameof(DiscriminatedUnion128Object));
  101. }
  102. #endif
  103. [FieldOffset(0)] private readonly int _discriminator; // note that we can't pack further because Object needs x8 alignment/padding on x64
  104. /// <summary>The value typed as Int64</summary>
  105. [FieldOffset(8)] public readonly long Int64;
  106. /// <summary>The value typed as UInt64</summary>
  107. [FieldOffset(8)] public readonly ulong UInt64;
  108. /// <summary>The value typed as Int32</summary>
  109. [FieldOffset(8)] public readonly int Int32;
  110. /// <summary>The value typed as UInt32</summary>
  111. [FieldOffset(8)] public readonly uint UInt32;
  112. /// <summary>The value typed as Boolean</summary>
  113. [FieldOffset(8)] public readonly bool Boolean;
  114. /// <summary>The value typed as Single</summary>
  115. [FieldOffset(8)] public readonly float Single;
  116. /// <summary>The value typed as Double</summary>
  117. [FieldOffset(8)] public readonly double Double;
  118. /// <summary>The value typed as DateTime</summary>
  119. [FieldOffset(8)] public readonly DateTime DateTime;
  120. /// <summary>The value typed as TimeSpan</summary>
  121. [FieldOffset(8)] public readonly TimeSpan TimeSpan;
  122. /// <summary>The value typed as Guid</summary>
  123. [FieldOffset(8)] public readonly Guid Guid;
  124. /// <summary>The value typed as Object</summary>
  125. [FieldOffset(24)] public readonly object Object;
  126. private DiscriminatedUnion128Object(int discriminator) : this()
  127. {
  128. _discriminator = discriminator;
  129. }
  130. /// <summary>Indicates whether the specified discriminator is assigned</summary>
  131. public bool Is(int discriminator) => _discriminator == discriminator;
  132. /// <summary>Create a new discriminated union value</summary>
  133. public DiscriminatedUnion128Object(int discriminator, long value) : this(discriminator) { Int64 = value; }
  134. /// <summary>Create a new discriminated union value</summary>
  135. public DiscriminatedUnion128Object(int discriminator, int value) : this(discriminator) { Int32 = value; }
  136. /// <summary>Create a new discriminated union value</summary>
  137. public DiscriminatedUnion128Object(int discriminator, ulong value) : this(discriminator) { UInt64 = value; }
  138. /// <summary>Create a new discriminated union value</summary>
  139. public DiscriminatedUnion128Object(int discriminator, uint value) : this(discriminator) { UInt32 = value; }
  140. /// <summary>Create a new discriminated union value</summary>
  141. public DiscriminatedUnion128Object(int discriminator, float value) : this(discriminator) { Single = value; }
  142. /// <summary>Create a new discriminated union value</summary>
  143. public DiscriminatedUnion128Object(int discriminator, double value) : this(discriminator) { Double = value; }
  144. /// <summary>Create a new discriminated union value</summary>
  145. public DiscriminatedUnion128Object(int discriminator, bool value) : this(discriminator) { Boolean = value; }
  146. /// <summary>Create a new discriminated union value</summary>
  147. public DiscriminatedUnion128Object(int discriminator, object value) : this(value != null ? discriminator : 0) { Object = value; }
  148. /// <summary>Create a new discriminated union value</summary>
  149. public DiscriminatedUnion128Object(int discriminator, DateTime? value) : this(value.HasValue ? discriminator: 0) { DateTime = value.GetValueOrDefault(); }
  150. /// <summary>Create a new discriminated union value</summary>
  151. public DiscriminatedUnion128Object(int discriminator, TimeSpan? value) : this(value.HasValue ? discriminator : 0) { TimeSpan = value.GetValueOrDefault(); }
  152. /// <summary>Create a new discriminated union value</summary>
  153. public DiscriminatedUnion128Object(int discriminator, Guid? value) : this(value.HasValue ? discriminator : 0) { Guid = value.GetValueOrDefault(); }
  154. /// <summary>Reset a value if the specified discriminator is assigned</summary>
  155. public static void Reset(ref DiscriminatedUnion128Object value, int discriminator)
  156. {
  157. if (value.Discriminator == discriminator) value = default;
  158. }
  159. /// <summary>The discriminator value</summary>
  160. public int Discriminator => _discriminator;
  161. }
  162. /// <summary>Represent multiple types as a union; this is used as part of OneOf -
  163. /// note that it is the caller's responsbility to only read/write the value as the same type</summary>
  164. [StructLayout(LayoutKind.Explicit)]
  165. public readonly partial struct DiscriminatedUnion128
  166. {
  167. #if !FEAT_SAFE
  168. unsafe static DiscriminatedUnion128()
  169. {
  170. if (sizeof(DateTime) > 16) throw new InvalidOperationException(nameof(DateTime) + " was unexpectedly too big for " + nameof(DiscriminatedUnion128));
  171. if (sizeof(TimeSpan) > 16) throw new InvalidOperationException(nameof(TimeSpan) + " was unexpectedly too big for " + nameof(DiscriminatedUnion128));
  172. if (sizeof(Guid) > 16) throw new InvalidOperationException(nameof(Guid) + " was unexpectedly too big for " + nameof(DiscriminatedUnion128));
  173. }
  174. #endif
  175. [FieldOffset(0)] private readonly int _discriminator; // note that we can't pack further because Object needs x8 alignment/padding on x64
  176. /// <summary>The value typed as Int64</summary>
  177. [FieldOffset(8)] public readonly long Int64;
  178. /// <summary>The value typed as UInt64</summary>
  179. [FieldOffset(8)] public readonly ulong UInt64;
  180. /// <summary>The value typed as Int32</summary>
  181. [FieldOffset(8)] public readonly int Int32;
  182. /// <summary>The value typed as UInt32</summary>
  183. [FieldOffset(8)] public readonly uint UInt32;
  184. /// <summary>The value typed as Boolean</summary>
  185. [FieldOffset(8)] public readonly bool Boolean;
  186. /// <summary>The value typed as Single</summary>
  187. [FieldOffset(8)] public readonly float Single;
  188. /// <summary>The value typed as Double</summary>
  189. [FieldOffset(8)] public readonly double Double;
  190. /// <summary>The value typed as DateTime</summary>
  191. [FieldOffset(8)] public readonly DateTime DateTime;
  192. /// <summary>The value typed as TimeSpan</summary>
  193. [FieldOffset(8)] public readonly TimeSpan TimeSpan;
  194. /// <summary>The value typed as Guid</summary>
  195. [FieldOffset(8)] public readonly Guid Guid;
  196. private DiscriminatedUnion128(int discriminator) : this()
  197. {
  198. _discriminator = discriminator;
  199. }
  200. /// <summary>Indicates whether the specified discriminator is assigned</summary>
  201. public bool Is(int discriminator) => _discriminator == discriminator;
  202. /// <summary>Create a new discriminated union value</summary>
  203. public DiscriminatedUnion128(int discriminator, long value) : this(discriminator) { Int64 = value; }
  204. /// <summary>Create a new discriminated union value</summary>
  205. public DiscriminatedUnion128(int discriminator, int value) : this(discriminator) { Int32 = value; }
  206. /// <summary>Create a new discriminated union value</summary>
  207. public DiscriminatedUnion128(int discriminator, ulong value) : this(discriminator) { UInt64 = value; }
  208. /// <summary>Create a new discriminated union value</summary>
  209. public DiscriminatedUnion128(int discriminator, uint value) : this(discriminator) { UInt32 = value; }
  210. /// <summary>Create a new discriminated union value</summary>
  211. public DiscriminatedUnion128(int discriminator, float value) : this(discriminator) { Single = value; }
  212. /// <summary>Create a new discriminated union value</summary>
  213. public DiscriminatedUnion128(int discriminator, double value) : this(discriminator) { Double = value; }
  214. /// <summary>Create a new discriminated union value</summary>
  215. public DiscriminatedUnion128(int discriminator, bool value) : this(discriminator) { Boolean = value; }
  216. /// <summary>Create a new discriminated union value</summary>
  217. public DiscriminatedUnion128(int discriminator, DateTime? value) : this(value.HasValue ? discriminator: 0) { DateTime = value.GetValueOrDefault(); }
  218. /// <summary>Create a new discriminated union value</summary>
  219. public DiscriminatedUnion128(int discriminator, TimeSpan? value) : this(value.HasValue ? discriminator : 0) { TimeSpan = value.GetValueOrDefault(); }
  220. /// <summary>Create a new discriminated union value</summary>
  221. public DiscriminatedUnion128(int discriminator, Guid? value) : this(value.HasValue ? discriminator : 0) { Guid = value.GetValueOrDefault(); }
  222. /// <summary>Reset a value if the specified discriminator is assigned</summary>
  223. public static void Reset(ref DiscriminatedUnion128 value, int discriminator)
  224. {
  225. if (value.Discriminator == discriminator) value = default;
  226. }
  227. /// <summary>The discriminator value</summary>
  228. public int Discriminator => _discriminator;
  229. }
  230. /// <summary>Represent multiple types as a union; this is used as part of OneOf -
  231. /// note that it is the caller's responsbility to only read/write the value as the same type</summary>
  232. [StructLayout(LayoutKind.Explicit)]
  233. public readonly partial struct DiscriminatedUnion64Object
  234. {
  235. #if !FEAT_SAFE
  236. unsafe static DiscriminatedUnion64Object()
  237. {
  238. if (sizeof(DateTime) > 8) throw new InvalidOperationException(nameof(DateTime) + " was unexpectedly too big for " + nameof(DiscriminatedUnion64Object));
  239. if (sizeof(TimeSpan) > 8) throw new InvalidOperationException(nameof(TimeSpan) + " was unexpectedly too big for " + nameof(DiscriminatedUnion64Object));
  240. }
  241. #endif
  242. [FieldOffset(0)] private readonly int _discriminator; // note that we can't pack further because Object needs x8 alignment/padding on x64
  243. /// <summary>The value typed as Int64</summary>
  244. [FieldOffset(8)] public readonly long Int64;
  245. /// <summary>The value typed as UInt64</summary>
  246. [FieldOffset(8)] public readonly ulong UInt64;
  247. /// <summary>The value typed as Int32</summary>
  248. [FieldOffset(8)] public readonly int Int32;
  249. /// <summary>The value typed as UInt32</summary>
  250. [FieldOffset(8)] public readonly uint UInt32;
  251. /// <summary>The value typed as Boolean</summary>
  252. [FieldOffset(8)] public readonly bool Boolean;
  253. /// <summary>The value typed as Single</summary>
  254. [FieldOffset(8)] public readonly float Single;
  255. /// <summary>The value typed as Double</summary>
  256. [FieldOffset(8)] public readonly double Double;
  257. /// <summary>The value typed as DateTime</summary>
  258. [FieldOffset(8)] public readonly DateTime DateTime;
  259. /// <summary>The value typed as TimeSpan</summary>
  260. [FieldOffset(8)] public readonly TimeSpan TimeSpan;
  261. /// <summary>The value typed as Object</summary>
  262. [FieldOffset(16)] public readonly object Object;
  263. private DiscriminatedUnion64Object(int discriminator) : this()
  264. {
  265. _discriminator = discriminator;
  266. }
  267. /// <summary>Indicates whether the specified discriminator is assigned</summary>
  268. public bool Is(int discriminator) => _discriminator == discriminator;
  269. /// <summary>Create a new discriminated union value</summary>
  270. public DiscriminatedUnion64Object(int discriminator, long value) : this(discriminator) { Int64 = value; }
  271. /// <summary>Create a new discriminated union value</summary>
  272. public DiscriminatedUnion64Object(int discriminator, int value) : this(discriminator) { Int32 = value; }
  273. /// <summary>Create a new discriminated union value</summary>
  274. public DiscriminatedUnion64Object(int discriminator, ulong value) : this(discriminator) { UInt64 = value; }
  275. /// <summary>Create a new discriminated union value</summary>
  276. public DiscriminatedUnion64Object(int discriminator, uint value) : this(discriminator) { UInt32 = value; }
  277. /// <summary>Create a new discriminated union value</summary>
  278. public DiscriminatedUnion64Object(int discriminator, float value) : this(discriminator) { Single = value; }
  279. /// <summary>Create a new discriminated union value</summary>
  280. public DiscriminatedUnion64Object(int discriminator, double value) : this(discriminator) { Double = value; }
  281. /// <summary>Create a new discriminated union value</summary>
  282. public DiscriminatedUnion64Object(int discriminator, bool value) : this(discriminator) { Boolean = value; }
  283. /// <summary>Create a new discriminated union value</summary>
  284. public DiscriminatedUnion64Object(int discriminator, object value) : this(value != null ? discriminator : 0) { Object = value; }
  285. /// <summary>Create a new discriminated union value</summary>
  286. public DiscriminatedUnion64Object(int discriminator, DateTime? value) : this(value.HasValue ? discriminator: 0) { DateTime = value.GetValueOrDefault(); }
  287. /// <summary>Create a new discriminated union value</summary>
  288. public DiscriminatedUnion64Object(int discriminator, TimeSpan? value) : this(value.HasValue ? discriminator : 0) { TimeSpan = value.GetValueOrDefault(); }
  289. /// <summary>Reset a value if the specified discriminator is assigned</summary>
  290. public static void Reset(ref DiscriminatedUnion64Object value, int discriminator)
  291. {
  292. if (value.Discriminator == discriminator) value = default;
  293. }
  294. /// <summary>The discriminator value</summary>
  295. public int Discriminator => _discriminator;
  296. }
  297. /// <summary>Represent multiple types as a union; this is used as part of OneOf -
  298. /// note that it is the caller's responsbility to only read/write the value as the same type</summary>
  299. [StructLayout(LayoutKind.Explicit)]
  300. public readonly partial struct DiscriminatedUnion32
  301. {
  302. [FieldOffset(0)] private readonly int _discriminator;
  303. /// <summary>The value typed as Int32</summary>
  304. [FieldOffset(4)] public readonly int Int32;
  305. /// <summary>The value typed as UInt32</summary>
  306. [FieldOffset(4)] public readonly uint UInt32;
  307. /// <summary>The value typed as Boolean</summary>
  308. [FieldOffset(4)] public readonly bool Boolean;
  309. /// <summary>The value typed as Single</summary>
  310. [FieldOffset(4)] public readonly float Single;
  311. private DiscriminatedUnion32(int discriminator) : this()
  312. {
  313. _discriminator = discriminator;
  314. }
  315. /// <summary>Indicates whether the specified discriminator is assigned</summary>
  316. public bool Is(int discriminator) => _discriminator == discriminator;
  317. /// <summary>Create a new discriminated union value</summary>
  318. public DiscriminatedUnion32(int discriminator, int value) : this(discriminator) { Int32 = value; }
  319. /// <summary>Create a new discriminated union value</summary>
  320. public DiscriminatedUnion32(int discriminator, uint value) : this(discriminator) { UInt32 = value; }
  321. /// <summary>Create a new discriminated union value</summary>
  322. public DiscriminatedUnion32(int discriminator, float value) : this(discriminator) { Single = value; }
  323. /// <summary>Create a new discriminated union value</summary>
  324. public DiscriminatedUnion32(int discriminator, bool value) : this(discriminator) { Boolean = value; }
  325. /// <summary>Reset a value if the specified discriminator is assigned</summary>
  326. public static void Reset(ref DiscriminatedUnion32 value, int discriminator)
  327. {
  328. if (value.Discriminator == discriminator) value = default;
  329. }
  330. /// <summary>The discriminator value</summary>
  331. public int Discriminator => _discriminator;
  332. }
  333. /// <summary>Represent multiple types as a union; this is used as part of OneOf -
  334. /// note that it is the caller's responsbility to only read/write the value as the same type</summary>
  335. [StructLayout(LayoutKind.Explicit)]
  336. public readonly partial struct DiscriminatedUnion32Object
  337. {
  338. [FieldOffset(0)] private readonly int _discriminator;
  339. /// <summary>The value typed as Int32</summary>
  340. [FieldOffset(4)] public readonly int Int32;
  341. /// <summary>The value typed as UInt32</summary>
  342. [FieldOffset(4)] public readonly uint UInt32;
  343. /// <summary>The value typed as Boolean</summary>
  344. [FieldOffset(4)] public readonly bool Boolean;
  345. /// <summary>The value typed as Single</summary>
  346. [FieldOffset(4)] public readonly float Single;
  347. /// <summary>The value typed as Object</summary>
  348. [FieldOffset(8)] public readonly object Object;
  349. private DiscriminatedUnion32Object(int discriminator) : this()
  350. {
  351. _discriminator = discriminator;
  352. }
  353. /// <summary>Indicates whether the specified discriminator is assigned</summary>
  354. public bool Is(int discriminator) => _discriminator == discriminator;
  355. /// <summary>Create a new discriminated union value</summary>
  356. public DiscriminatedUnion32Object(int discriminator, int value) : this(discriminator) { Int32 = value; }
  357. /// <summary>Create a new discriminated union value</summary>
  358. public DiscriminatedUnion32Object(int discriminator, uint value) : this(discriminator) { UInt32 = value; }
  359. /// <summary>Create a new discriminated union value</summary>
  360. public DiscriminatedUnion32Object(int discriminator, float value) : this(discriminator) { Single = value; }
  361. /// <summary>Create a new discriminated union value</summary>
  362. public DiscriminatedUnion32Object(int discriminator, bool value) : this(discriminator) { Boolean = value; }
  363. /// <summary>Create a new discriminated union value</summary>
  364. public DiscriminatedUnion32Object(int discriminator, object value) : this(value != null ? discriminator : 0) { Object = value; }
  365. /// <summary>Reset a value if the specified discriminator is assigned</summary>
  366. public static void Reset(ref DiscriminatedUnion32Object value, int discriminator)
  367. {
  368. if (value.Discriminator == discriminator) value = default;
  369. }
  370. /// <summary>The discriminator value</summary>
  371. public int Discriminator => _discriminator;
  372. }
  373. }