DiscriminatedUnion.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. using System;
  2. using System.Diagnostics.CodeAnalysis;
  3. namespace NModbus.Utility
  4. {
  5. /// <summary>
  6. /// Possible options for DiscriminatedUnion type.
  7. /// </summary>
  8. public enum DiscriminatedUnionOption
  9. {
  10. /// <summary>
  11. /// Option A.
  12. /// </summary>
  13. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "A")]
  14. A,
  15. /// <summary>
  16. /// Option B.
  17. /// </summary>
  18. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "B")]
  19. B
  20. }
  21. /// <summary>
  22. /// A data type that can store one of two possible strongly typed options.
  23. /// </summary>
  24. /// <typeparam name="TA">The type of option A.</typeparam>
  25. /// <typeparam name="TB">The type of option B.</typeparam>
  26. public class DiscriminatedUnion<TA, TB>
  27. {
  28. private TA optionA;
  29. private TB optionB;
  30. private DiscriminatedUnionOption option;
  31. /// <summary>
  32. /// Gets the value of option A.
  33. /// </summary>
  34. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "A")]
  35. public TA A
  36. {
  37. get
  38. {
  39. if (this.Option != DiscriminatedUnionOption.A)
  40. {
  41. string msg = $"{DiscriminatedUnionOption.A} is not a valid option for this discriminated union instance.";
  42. throw new InvalidOperationException(msg);
  43. }
  44. return this.optionA;
  45. }
  46. }
  47. /// <summary>
  48. /// Gets the value of option B.
  49. /// </summary>
  50. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "B")]
  51. public TB B
  52. {
  53. get
  54. {
  55. if (this.Option != DiscriminatedUnionOption.B)
  56. {
  57. string msg = $"{DiscriminatedUnionOption.B} is not a valid option for this discriminated union instance.";
  58. throw new InvalidOperationException(msg);
  59. }
  60. return this.optionB;
  61. }
  62. }
  63. /// <summary>
  64. /// Gets the discriminated value option set for this instance.
  65. /// </summary>
  66. public DiscriminatedUnionOption Option => this.option;
  67. /// <summary>
  68. /// Factory method for creating DiscriminatedUnion with option A set.
  69. /// </summary>
  70. [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes", Justification = "Factory method.")]
  71. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "0#a")]
  72. public static DiscriminatedUnion<TA, TB> CreateA(TA a)
  73. {
  74. return new DiscriminatedUnion<TA, TB>() { option = DiscriminatedUnionOption.A, optionA = a };
  75. }
  76. /// <summary>
  77. /// Factory method for creating DiscriminatedUnion with option B set.
  78. /// </summary>
  79. [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes", Justification = "Factory method.")]
  80. [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "0#b")]
  81. public static DiscriminatedUnion<TA, TB> CreateB(TB b)
  82. {
  83. return new DiscriminatedUnion<TA, TB>() { option = DiscriminatedUnionOption.B, optionB = b };
  84. }
  85. /// <summary>
  86. /// Returns a <see cref="T:System.String" /> that represents the current <see cref="T:System.Object" />.
  87. /// </summary>
  88. /// <returns>
  89. /// A <see cref="T:System.String" /> that represents the current <see cref="T:System.Object" />.
  90. /// </returns>
  91. public override string ToString()
  92. {
  93. string value = null;
  94. switch (Option)
  95. {
  96. case DiscriminatedUnionOption.A:
  97. value = A.ToString();
  98. break;
  99. case DiscriminatedUnionOption.B:
  100. value = B.ToString();
  101. break;
  102. }
  103. return value;
  104. }
  105. }
  106. }