Skip to content

Commit f7a320a

Browse files
committed
Partially fixed #266
1 parent 155e53a commit f7a320a

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

src/DotNext.Tests/ResultTests.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,4 +254,15 @@ public static void ValueRef()
254254
result = Result.FromException<int>(new ArithmeticException());
255255
Throws<ArithmeticException>(() => result.ValueRef);
256256
}
257+
258+
[Fact]
259+
public static void NonNullResult()
260+
{
261+
var result = default(Result<string>).EnsureNotNull();
262+
False(result.IsSuccessful);
263+
Throws<NullReferenceException>(() => result.Value);
264+
265+
result = Result.FromValue("").EnsureNotNull();
266+
True(result.IsSuccessful);
267+
}
257268
}

src/DotNext/Result.cs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ public static class Result
5151
/// </summary>
5252
/// <param name="resultType">The type of <see cref="Result{T}"/>.</param>
5353
/// <returns><see langword="true"/>, if specified type is result type; otherwise, <see langword="false"/>.</returns>
54-
public static bool IsResult(this Type resultType) => resultType.IsConstructedGenericType && resultType.GetGenericTypeDefinition().IsOneOf([typeof(Result<>), typeof(Result<,>)]);
54+
public static bool IsResult(this Type resultType) => resultType.IsConstructedGenericType &&
55+
resultType.GetGenericTypeDefinition().IsOneOf([typeof(Result<>), typeof(Result<,>)]);
5556

5657
/// <summary>
5758
/// Returns the underlying type argument of the specified result type.
@@ -75,6 +76,30 @@ public static class Result
7576
/// <param name="e">The exception to be placed to the container.</param>
7677
/// <returns>The exception encapsulated by <see cref="Result{T}"/>.</returns>
7778
public static Result<T> FromException<T>(Exception e) => new(e);
79+
80+
/// <summary>
81+
/// Ensures that the specified result doesn't contain null value.
82+
/// </summary>
83+
/// <param name="result">The result to be checked.</param>
84+
/// <typeparam name="T">The type of the result.</typeparam>
85+
/// <returns>The result containing non-null value; or <see cref="NullReferenceException"/> as an error.</returns>
86+
public static Result<T> EnsureNotNull<T>(this Result<T?> result)
87+
where T : class
88+
=> EnsureNotNull<T, NullReferenceException>(result);
89+
90+
/// <summary>
91+
/// Ensures that the specified result doesn't contain null value.
92+
/// </summary>
93+
/// <param name="result">The result to be checked.</param>
94+
/// <typeparam name="T">The type of the result.</typeparam>
95+
/// <typeparam name="TException">The type of the exception to be returned from the null result.</typeparam>
96+
/// <returns>The result containing non-null value; or <paramref cref="TException"/> as an error.</returns>
97+
public static Result<T> EnsureNotNull<T, TException>(this Result<T?> result)
98+
where T : class
99+
where TException : Exception, new()
100+
=> result.IsNull
101+
? FromException<T>(ExceptionDispatchInfo.SetCurrentStackTrace(new TException()))
102+
: result!;
78103
}
79104

80105
/// <summary>
@@ -102,6 +127,10 @@ public Result(Exception error)
102127
{
103128
}
104129

130+
[JsonIgnore]
131+
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
132+
internal bool IsNull => exception is null && value is null;
133+
105134
private Result(ExceptionDispatchInfo dispatchInfo)
106135
{
107136
Unsafe.SkipInit(out value);

0 commit comments

Comments
 (0)