I have a generic class to represent either a result or an error, but not both:
public class Result<TValue, TError>
where TValue : notnull
where TError : notnull
{
private readonly bool succeeded;
private readonly TValue? value;
private readonly TError? error;
public static Result<TValue, TError> Success(TValue value) =>
new(true, value ?? throw new ArgumentNullException(nameof(value)), default);
public static Result<TValue, TError> Failure(TError error) =>
new(false, default, error ?? throw new ArgumentNullException(nameof(error)));
protected Result(bool succeeded, TValue? value, TError? error)
{
this.succeeded = succeeded;
this.value = value;
this.error = error;
}
public bool Successful(
[NotNullWhen(true)] out TValue? value,
[NotNullWhen(false)] out TError? error)
{
if (succeeded)
{
value = this.value!;
error = default;
return true;
}
else
{
value = default;
error = this.error!;
return false;
}
}
}
This works as I want for classes. For example, if TValue is object
then the value
field and value
parameters are object?
. However, I've realised that when a generic type parameter is a value type, decorating it with the ?
doesn't make it Nullable
. This is presumably because doing so would change the underlying type rather than just commenting on its nullability. Is there any way to reference the Nullable
version of a generic type?
CodePudding user response:
This is language limitation. See official docs
If the type argument for T is a value type, T? references the same value type, T. For example, if T is an int, the T? is also an int.