Why is 'struct Nullable<T>' not a struct?
c#, nullable, struct
Solution
It is a `struct`. It just doesn't satisfy the value type generic type parameter constraint. From 10.1.5 of the language specification:
The value type constraint specifies that a type argument used for the type parameter must be a non-nullable value 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.
So, the `where T : struct` doesn't mean what you think it means.
Basically why is the following invalid in C#?
Because `where T : struct` can only be satisfied by `T` that are non-nullable value types. `Nullable<TNonNullableValueType>` does not satisfy this constraint.
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`.
[I] can fix it by creating my own nullable struct class but
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.
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." What's the point of nesting this? That is, what's the point of `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). For example, what is an `int??`? It represents a storage location that represents the value is missing or is an `int?`, which is itself a storage location that represents the value is missing or is an `int`? What's the use?
Problem
Basically why is the following invalid in 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? 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; } } ```