【发布时间】:2022-06-10 21:57:44
【问题描述】:
我有一个通用类来表示结果或错误,但不能同时表示:
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;
}
}
}
这适用于我想要的课程。例如,如果 TValue 为object,则value 字段和value 参数为object?。但是,我已经意识到,当泛型类型参数是值类型时,用? 装饰它不会使其成为Nullable。这大概是因为这样做会改变底层类型,而不仅仅是评论它的可空性。有没有办法引用泛型类型的Nullable 版本?
【问题讨论】:
-
我想你知道如果你约束
where TValue : struct,那么TValue?总是意味着Nullable<TValue>。但是你不能在TValue是引用类型的情况下使用你的类型。 -
感谢@JeppeStigNielsen。是的,我尝试过创建
、 、 和 组合,但这很可惜,因为除了复制之外,每个版本需要一个不同的名称。 -
也许你必须放弃所有
null的东西并写或找到一个option type 来代替(如Maybe<T>或Optional<T>或其他东西;其中T不限于值类型),如线程Optional return in C#.Net 或其他。当然,??之类的语法和[NotNullWhen(...)]之类的属性将无法使用。 -
感谢@JeppeStigNielsen。这可能是要走的路。我确实喜欢 [NotNullWhen],因为代码分析在调用者站点上运行良好,但这似乎不适用于 Nullables。谢谢你的建议。
标签: c# generics nullable boxing nullable-reference-types