gpt4 book ai didi

c# - C#'s can' t 使 `notnull` 类型可以为空

转载 作者:行者123 更新时间:2023-12-01 01:22:29 26 4
gpt4 key购买 nike

我正在尝试创建一个类似于 Rust 的类型 Result或 Haskell 的 Either我已经走了这么远:

public struct Result<TResult, TError>
where TResult : notnull
where TError : notnull
{
private readonly OneOf<TResult, TError> Value;
public Result(TResult result) => Value = result;
public Result(TError error) => Value = error;

public static implicit operator Result<TResult, TError>(TResult result)
=> new Result<TResult, TError>(result);

public static implicit operator Result<TResult, TError>(TError error)
=> new Result<TResult, TError>(error);

public void Deconstruct(out TResult? result, out TError? error)
{
result = (Value.IsT0) ? Value.AsT0 : (TResult?)null;
error = (Value.IsT1) ? Value.AsT1 : (TError?)null;
}
}

鉴于这两种类型的参数都被限制为 notnull ,为什么它会提示(任何类型参数后面带有可空的 ? 符号):

A nullable type parameter must be known to be a value type or non-nullable reference type. Consider adding a 'class', 'struct', or type constraint.



?

我在 .NET Core 3 上使用 C# 8,并启用了可为空引用类型。

最佳答案

基本上你要求的东西不能用 IL 表示。可空值类型和可空引用类型是非常不同的野兽,虽然它们在源代码中看起来相似,但 IL 却大不相同。值类型的可为空版本 T是一种不同的类型( Nullable<T> ),而引用类型的可为空版本 T是相同的类型,具有告诉编译器期望什么的属性。

考虑这个更简单的例子:

public class Foo<T> where T : notnull
{
public T? GetNullValue() =>
}

出于同样的原因,这是无效的。

如果我们约束 T是一个结构体,然后为 GetNullValue 生成的 IL方法的返回类型为 Nullable<T> .

如果我们约束 T为不可为空的引用类型,则为 GetNullValue 生成的 IL方法的返回类型为 T ,但具有可空性方面的属性。

编译器无法为返回类型为 T 的方法生成 IL。和 Nullable<T>同时。

这基本上是可空引用类型根本不是 CLR 概念的所有结果 - 它只是编译器魔术,可以帮助您在代码中表达意图并让编译器在编译时执行一些检查。

错误消息并不像它可能的那样清晰。 T已知为“值类型或不可为空的引用类型”。更精确(但更冗长)的错误消息是:

A nullable type parameter must be known to be a value type, or known to be a non-nullable reference type. Consider adding a 'class', 'struct', or type constraint.



那时,错误将合理地应用于我们的代码 - 类型参数不是“已知为值类型”,也不是“已知为不可为空的引用类型”。已知它是两者之一,但编译器需要知道哪个。

关于c# - C#'s can' t 使 `notnull` 类型可以为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58852272/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com