繁体   English   中英

为什么&#39;struct Nullable <T> &#39;不是结构?

[英]Why is 'struct Nullable<T>' not a struct?

基本上为什么C#中的以下内容无效? 我可以找到很多好的用途,实际上可以通过创建我自己的可空结构类来修复它,但C#规范(以及编译器)为什么以及如何阻止它呢?

以下是我所说的部分例子。

struct MyNullable<T> where T : struct
{
    public T Value;
    public bool HasValue;

    // Need to overide equals, as well as provide static implicit/explit cast operators
}

class Program
{
    static void Main(string[] args)
    {
        // Compiles fine and works as expected
        MyNullable<Double> NullableDoubleTest;
        NullableDoubleTest.Value = 63.0;

        // Also compiles fine and works as expected
        MyNullable<MyNullable<Double>> NullableNullableTest;
        NullableNullableTest.Value.Value = 63.0;

        // Fails to compile...despite Nullable being a struct
        // Error: The type 'double?' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'ConsoleApplication1.MyNullable<T>'
        MyNullable<Nullable<Double>> MyNullableSuperStruct;
    }
}

这是一个struct 它只是不满足值类型泛型类型参数约束。 从10.1.5的语言规范:

值类型约束指定用于type参数的类型参数必须是非可空值类型。 具有值类型约束的所有非可空结构类型,枚举类型和类型参数都满足此约束。 请注意,虽然归类为值类型,但可空类型(第4.1.10节)不满足值类型约束。

那么, where T : struct并不代表你认为它意味着什么。

基本上为什么C#中的以下内容无效?

因为where T : struct只能由不满足值的类型的T来满足。 Nullable<TNonNullableValueType>不满足此约束。

为什么以及编译器如何阻止它呢?

为什么? 符合规范。 怎么样? 通过执行语法和语义分析并确定您提供了一个不满足泛型类型约束的泛型类型参数Twhere T : struct

[I]可以通过创建我自己的可空结构类来修复它

不,你的版本没有修复它。 它基本上与Nullable<T>完全相同,除非您没有得到编译器的特殊处理,并且您将导致编译器的实现不会打包的一些装箱。

我可以找到很多好的用途

真? 如? 请记住, Nullable<T>的基本思想是拥有一个可以包含T的存储位置,或者可以表示“缺少值”。 嵌套这个有什么意义? 也就是说, Nullable<Nullable<T>>什么? 它甚至没有概念意义。 这可能就是它被禁止的原因,但我只是在猜测( Eric Lippert已经证实这种推测是正确的 )。 例如,什么是int?? 它表示一个存储位置,表示缺少值或是一个int? ,它本身是一个存储位置,表示缺少值或是一个int 什么用途?

结构约束拨号为nullables的一个原因是我们希望能够使用T? 在通用方法中。 如果struct允许可以为空的值类型,编译器将不得不禁止T?

在其他情况下,可空类型必须在编译器中具有特殊处理:

  • null关键字必须可以隐式转换为可空类型; 对于值类型,这是不可能的。
  • 可以将Nullable值类型与null关键字进行比较; 对于不可为空的值类型,此比较始终返回false。
  • 可空值类型适用于?? 操作; 非nullables不。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM