OneOf.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. namespace MeloongCore;
  2. public readonly struct OneOf<T1, T2> {
  3. private readonly int _index = -1; // -1 表示未初始化(这是一个 struct,所以这可以让默认值不为 0)
  4. private readonly T1? _value1;
  5. private readonly T2? _value2;
  6. public static implicit operator OneOf<T1, T2>(T1 value) => new(1, value, default);
  7. public static implicit operator OneOf<T1, T2>(T2 value) => new(2, default, value);
  8. public static implicit operator T1(OneOf<T1, T2> value) => value.As<T1>();
  9. public static implicit operator T2(OneOf<T1, T2> value) => value.As<T2>();
  10. private OneOf(int index, T1? value1, T2? value2) {
  11. _index = index;
  12. _value1 = value1;
  13. _value2 = value2;
  14. }
  15. /// <summary>
  16. /// 对不同类型执行不同的操作,并返回同一个值。
  17. /// </summary>
  18. public TResult Switch<TResult>(Func<T1, TResult> f1, Func<T2, TResult> f2) => _index switch {
  19. 1 => f1(_value1!),
  20. 2 => f2(_value2!),
  21. _ => throw new InvalidOperationException()
  22. };
  23. /// <summary>
  24. /// 对不同类型执行不同的操作。
  25. /// </summary>
  26. public void Switch(Action<T1> f1, Action<T2> f2) {
  27. if (_index == 1) f1(_value1!);
  28. else if (_index == 2) f2(_value2!);
  29. else throw new InvalidOperationException();
  30. }
  31. /// <summary>
  32. /// 判断当前的类型是否为 T。
  33. /// </summary>
  34. public bool Is<T>() => _index switch {
  35. 1 when typeof(T) == typeof(T1) => true,
  36. 2 when typeof(T) == typeof(T2) => true,
  37. _ => false
  38. };
  39. public bool IsT1() => _index == 1;
  40. public bool IsT2() => _index == 2;
  41. /// <summary>
  42. /// 假定当前的类型为 T,并返回该值。
  43. /// 若当前值的类型不为 T,则抛出 <see cref="InvalidOperationException"/>。
  44. /// </summary>
  45. public T As<T>() => _index switch {
  46. 1 when typeof(T) == typeof(T1) => (T)(object)_value1!,
  47. 2 when typeof(T) == typeof(T2) => (T)(object)_value2!,
  48. _ => throw new InvalidOperationException()
  49. };
  50. public T1 AsT1() => _index switch { 1 => _value1!, _ => throw new InvalidOperationException() };
  51. public T2 AsT2() => _index switch { 2 => _value2!, _ => throw new InvalidOperationException() };
  52. }
  53. public readonly struct OneOf<T1, T2, T3> {
  54. private readonly int _index = -1; // -1 表示未初始化(这是一个 struct,所以这可以让默认值不为 0)
  55. private readonly T1? _value1;
  56. private readonly T2? _value2;
  57. private readonly T3? _value3;
  58. public static implicit operator OneOf<T1, T2, T3>(T1 value) => new(1, value, default, default);
  59. public static implicit operator OneOf<T1, T2, T3>(T2 value) => new(2, default, value, default);
  60. public static implicit operator OneOf<T1, T2, T3>(T3 value) => new(3, default, default, value);
  61. public static implicit operator T1(OneOf<T1, T2, T3> value) => value.As<T1>();
  62. public static implicit operator T2(OneOf<T1, T2, T3> value) => value.As<T2>();
  63. public static implicit operator T3(OneOf<T1, T2, T3> value) => value.As<T3>();
  64. private OneOf(int index, T1? value1, T2? value2, T3? value3) {
  65. _index = index;
  66. _value1 = value1;
  67. _value2 = value2;
  68. _value3 = value3;
  69. }
  70. /// <summary>
  71. /// 对不同类型执行不同的操作,并返回同一个值。
  72. /// </summary>
  73. public TResult Switch<TResult>(Func<T1, TResult> f1, Func<T2, TResult> f2, Func<T3, TResult> f3) => _index switch {
  74. 1 => f1(_value1!),
  75. 2 => f2(_value2!),
  76. 3 => f3(_value3!),
  77. _ => throw new InvalidOperationException()
  78. };
  79. /// <summary>
  80. /// 对不同类型执行不同的操作。
  81. /// </summary>
  82. public void Switch(Action<T1> f1, Action<T2> f2, Action<T3> f3) {
  83. if (_index == 1) f1(_value1!);
  84. else if (_index == 2) f2(_value2!);
  85. else if (_index == 3) f3(_value3!);
  86. else throw new InvalidOperationException();
  87. }
  88. /// <summary>
  89. /// 判断当前的类型是否为 T。
  90. /// </summary>
  91. public bool Is<T>() => _index switch {
  92. 1 when typeof(T) == typeof(T1) => true,
  93. 2 when typeof(T) == typeof(T2) => true,
  94. 3 when typeof(T) == typeof(T3) => true,
  95. _ => false
  96. };
  97. public bool IsT1() => _index == 1;
  98. public bool IsT2() => _index == 2;
  99. public bool IsT3() => _index == 3;
  100. /// <summary>
  101. /// 假定当前的类型为 T,并返回该值。
  102. /// 若当前值的类型不为 T,则抛出 <see cref="InvalidOperationException"/>。
  103. /// </summary>
  104. public T As<T>() => _index switch {
  105. 1 when typeof(T) == typeof(T1) => (T) (object) _value1!,
  106. 2 when typeof(T) == typeof(T2) => (T) (object) _value2!,
  107. 3 when typeof(T) == typeof(T3) => (T) (object) _value3!,
  108. _ => throw new InvalidOperationException()
  109. };
  110. public T1 AsT1() => _index switch { 1 => _value1!, _ => throw new InvalidOperationException() };
  111. public T2 AsT2() => _index switch { 2 => _value2!, _ => throw new InvalidOperationException() };
  112. public T3 AsT3() => _index switch { 3 => _value3!, _ => throw new InvalidOperationException() };
  113. }