From a56a4ff5f2bdb71fcf6d355ba44b59cbe5ffd7f2 Mon Sep 17 00:00:00 2001 From: Kyle Ratti Date: Wed, 7 Feb 2024 20:57:33 -0500 Subject: [PATCH] fix: handle nullable value types in Maybe.Cast --- Base.Tests/Structures/MaybeTests.cs | 58 +++++++++++++++++++++++++++++ Base/Structures/Maybe.cs | 9 ++++- 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/Base.Tests/Structures/MaybeTests.cs b/Base.Tests/Structures/MaybeTests.cs index 3a377c6..ea13305 100644 --- a/Base.Tests/Structures/MaybeTests.cs +++ b/Base.Tests/Structures/MaybeTests.cs @@ -90,4 +90,62 @@ public class MaybeTests Assert.That(result.HasValue, Is.True); Assert.That(result.Value, Is.EqualTo(30)); } + + [Test] + public void Cast_ToNullableReferenceType_ReturnsEmptyMaybe_WhenHasNoValue() + { + // Arrange + var maybe = Maybe.Empty(); + + // Act + var result = maybe.Cast(); + + // Assert + Assert.That(result, Is.InstanceOf>()); + Assert.That(result.HasValue, Is.False); + } + + [Test] + public void Cast_ToNullableReferenceType_ReturnsMaybe_WhenHasValue() + { + // Arrange + var maybe = Maybe.Just("banana"); + + // Act + var result = maybe.Cast(); + + // Assert + Assert.That(result, Is.InstanceOf>()); + Assert.That(result.HasValue, Is.True); + Assert.That(result.Value, Is.EqualTo("banana")); + } + + [Test] + public void Cast_ToNullableValueType_ReturnsEmptyMaybe_WhenHasNoValue() + { + // Arrange + var maybe = Maybe.Empty(); + + // Act + var result = maybe.Cast(); + + // Assert + Assert.That(result, Is.InstanceOf>()); + Assert.That(result.HasValue, Is.False); + } + + [Test] + public void Cast_ToNullableValueType_ReturnsMaybe_WhenHasValue() + { + // Arrange + var maybe = Maybe.Just(25); + + // Act + var result = maybe.Cast(); + + // Assert + Assert.That(result, Is.InstanceOf>()); + Assert.That(result.HasValue, Is.True); + Assert.That(result.Value, Is.EqualTo(25)); + } } diff --git a/Base/Structures/Maybe.cs b/Base/Structures/Maybe.cs index 6d06d0e..39b2eca 100644 --- a/Base/Structures/Maybe.cs +++ b/Base/Structures/Maybe.cs @@ -70,7 +70,14 @@ public readonly struct Maybe try { - return (TOutput)Convert.ChangeType(Value, typeof(TOutput))!; + var t = typeof(TOutput); + t = Nullable.GetUnderlyingType(t) ?? t; + + var output = Value == null + ? default + : (TOutput)Convert.ChangeType(Value, t); + + return Maybe.Just(output, hasValue: _ => output != null)!; } catch (InvalidCastException) {