【问题标题】:Why is "default" different from "null" when assigning to a nullable type constrained by notnull?为什么在分配给受 notnull 约束的可空类型时,“默认”与“空”不同?
【发布时间】:2022-02-28 06:12:58
【问题描述】:

考虑这个最小的例子:

class A<T> where T : notnull
{
    public T? Item; // OK!
    public T? Something() => default; // OK!
    public void Meow(ref T? thing1, out T? thing2) { thing2 = default; } // OK!
    void Something(A<T>? other)
    {
        // OK!
        Item = other is null ? default : other.Item;

        // Error CS0403 : Cannot convert null to type parameter 'T' because it could be a non-nullable value type. Consider using 'default(T)' instead.
        Item = other is null ? null : other.Item;

        // Error CS8978 :  'T' cannot be made nullable.
        Item = other?.Item;
        Item = other?.Item ?? default;
        var x = other?.Item;
    }
    void Weird<U>(A<U>? other) where U : unmanaged
    {
        // OK!
        var x = other?.Item;
    }
    void Weird2<U>(A<U>? other) where U : class
    {
        // OK!
        var x = other?.Item;
    }
    void Weird3<U>(A<U>? other) where U : struct
    {
        // OK!
        var x = other?.Item;
    }
}

T 不为空

T? 要么是 T 要么是 null ...不是吗?在什么情况下这不是真的?

如果Tstruct那么ItemNullable&lt;T&gt;,可以由null分配

如果Tclass,那么“项目”就是T?,也可以由null 分配

我什至让T unmanaged 只是为了仔细检查(它应该是struct 的子集),并且可以由null 分配

...

那么存在什么类型的T 使得T? 不能保存值null

...我也不太确定我问的问题是否正确...我真正的问题是“为什么它不起作用!!?!?!” :)

注意:此处已正确回答了类似问题:C#'s can't make `notnull` type nullable ... 但该答案适用于 C# 8 ... 从 C# 9 及更高版本开始,不再是这种情况

我还会在这里指出文档:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters ... 基本上说notnull 表示类/结构

...

编辑(事后考虑):如果是 IL 问题(IL 需要知道它是可空引用类型还是可空引用类型)...那么为什么 default 有效而 null 无效?显然 某些 版本的 IL 可以工作,所以这只是语言缺陷/怪癖?

【问题讨论】:

  • 为什么你认为 C# 9.0 中有不同的规则?这些链接都没有提供证据
  • 将您的 csproj 设置为 LangVersion 8.0 并尝试 Jon Skeet 的示例(来自第一个链接)。编译器会告诉你,除非你使用 9.0 或更高版本,否则它不会工作。

标签: c# generics non-nullable


【解决方案1】:

Welp,我发布了一个答案(因为没有其他人这样做),在此处将其作为错误发布后:https://github.com/dotnet/roslyn/issues/59805

Tint 时,答案是T? 不是int?T? 就是 int

这很疯狂:)

更奇怪的是,如果你告诉编译器 Tstruct,那么当 Tint 时,T? 会突然变成 int?。 p>

很奇怪。不过没关系。就这样吧。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多