简体   繁体   English

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

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

Basically why is the following invalid in C#? 基本上为什么C#中的以下内容无效? I can find plenty of good uses for it and in fact can fix it by creating my own nullable struct class but why and how does the C# specification (and hence the compiler) prevent it? 我可以找到很多好的用途,实际上可以通过创建我自己的可空结构类来修复它,但C#规范(以及编译器)为什么以及如何阻止它呢?

The below is a partial example of what I'm talking about. 以下是我所说的部分例子。

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;
    }
}

It is a struct . 这是一个struct It just doesn't satisfy the value type generic type parameter constraint. 它只是不满足值类型泛型类型参数约束。 From 10.1.5 of the language specification: 从10.1.5的语言规范:

The value type constraint specifies that a type argument used for the type parameter must be a non-nullable value type. 值类型约束指定用于type参数的类型参数必须是非可空值类型。 All non-nullable struct types, enum types, and type parameters having the value type constraint satisfy this constraint. 具有值类型约束的所有非可空结构类型,枚举类型和类型参数都满足此约束。 Note that although classified as a value type, a nullable type (§4.1.10) does not satisfy the value type constraint. 请注意,虽然归类为值类型,但可空类型(第4.1.10节)不满足值类型约束。

So, the where T : struct doesn't mean what you think it means. 那么, where T : struct并不代表你认为它意味着什么。

Basically why is the following invalid in C#? 基本上为什么C#中的以下内容无效?

Because where T : struct can only be satisfied by T that are non-nullable value types. 因为where T : struct只能由不满足值的类型的T来满足。 Nullable<TNonNullableValueType> does not satisfy this constraint. Nullable<TNonNullableValueType>不满足此约束。

why and how does the compiler prevent it? 为什么以及编译器如何阻止它呢?

Why? 为什么? To be consistent with the specification. 符合规范。 How? 怎么样? By performing syntactic and semantic analysis and determining that you've supplied a generic type parameter T that doesn't satisfy the generic type constraint where T : struct . 通过执行语法和语义分析并确定您提供了一个不满足泛型类型约束的泛型类型参数Twhere T : struct

[I] can fix it by creating my own nullable struct class but [I]可以通过创建我自己的可空结构类来修复它

No, you're version doesn't fix it. 不,你的版本没有修复它。 It's basically exactly the same as Nullable<T> except you don't get special handling by the compiler, and you're going to cause some boxing that the compiler's implementation won't box. 它基本上与Nullable<T>完全相同,除非您没有得到编译器的特殊处理,并且您将导致编译器的实现不会打包的一些装箱。

I can find plenty of good uses for it 我可以找到很多好的用途

Really? 真? Such as? 如? Keep in mind, the basic idea of Nullable<T> is to have a storage location that can contain T or can represent "the value is missing." 请记住, Nullable<T>的基本思想是拥有一个可以包含T的存储位置,或者可以表示“缺少值”。 What's the point of nesting this? 嵌套这个有什么意义? That is, what's the point of Nullable<Nullable<T>> ? 也就是说, Nullable<Nullable<T>>什么? It doesn't even make conceptual sense. 它甚至没有概念意义。 That might be why it's prohibited, but I'm merely speculating ( Eric Lippert has confirmed that this speculation is correct ). 这可能就是它被禁止的原因,但我只是在猜测( Eric Lippert已经证实这种推测是正确的 )。 For example, what is an int?? 例如,什么是int?? ? It represents a storage location that represents the value is missing or is an int? 它表示一个存储位置,表示缺少值或是一个int? , which is itself a storage location that represents the value is missing or is an int ? ,它本身是一个存储位置,表示缺少值或是一个int What's the use? 什么用途?

One reason for the struct constraint's diallowing nullables is that we want to be able to use T? 结构约束拨号为nullables的一个原因是我们希望能够使用T? in generic methods. 在通用方法中。 If struct permitted nullable value types, the compiler would have to prohibit T? 如果struct允许可以为空的值类型,编译器将不得不禁止T? .

The nullable type must have special handling in the compiler in other cases as well: 在其他情况下,可空类型必须在编译器中具有特殊处理:

  • The null keyword must be implicitly convertible to a nullable type; null关键字必须可以隐式转换为可空类型; this is impossible with a value type. 对于值类型,这是不可能的。
  • Nullable value types can be compared with the null keyword; 可以将Nullable值类型与null关键字进行比较; with non-nullable value types, this comparison always returns false. 对于不可为空的值类型,此比较始终返回false。
  • Nullable value types work with the ?? 可空值类型适用于?? operator; 操作; non-nullables do not. 非nullables不。

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

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