7

Does anyone know why this code doesn't compile?

Nullable<Nullable<int>> n = null;

I realize Nullable has a constraint

where T : struct

But Nullable is struct. I also know this constraint has a restriction "The type argument must be a value type. Any value type except Nullable can be specified." (https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters). So how does it work? Is this solved on compiler level?

James Thorpe
  • 29,949
  • 5
  • 70
  • 88
srv52
  • 81
  • 4
  • 1
    What would be the point of a nested nullable? – Kell Sep 06 '17 at 12:59
  • Nullable [Source](https://referencesource.microsoft.com/#mscorlib/system/nullable.cs) for reference. I'm not actually seeing where the restriction comes from. `T` is restricted to `struct`, and `Nullable` is defined as a `struct`, so logically, it should work. Not that I can't think of any sane reason to do it. – Bradley Uffner Sep 06 '17 at 13:02

1 Answers1

6

The error message is:

The type int? must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method Nullable<T>

So it must not only be a value type but a non-nullable value type. But Nullable<int> is a nullable value type.

Here's the compiler error CS0453 which also shows this example:

This error occurs when you use a non-value type argument in instantiating a generic type or method which has the value constraint on it. It can also occur when you use a nullable value type argument.

Q: Is this solved on compiler level?

Yes, which means it' not very interesting to know how they achieved this constraint. It's an implementation detail of the compiler which doesn't need to use a C# language feature.


Why is not allowed?

Well, what would be the benefit of a Nullable<Nulable<int>>? Nullables were introduced to give value types the opportunity to be null(so undefined, without value). This is already achieved for a Nullable<int>, it can be null. So by nesting it in another nullable you would not get anything. It's not allowed for the same reason why you can't have a Nullable<string>, a string as every other reference type can already be null.

Tim Schmelter
  • 429,027
  • 67
  • 649
  • 891
  • 2
    Any idea on how this behaviour is actually archieved? I'm not aware of any constraint for non-nullable types (or I don't know them yet) – CShark Sep 06 '17 at 13:02
  • The compiler can impose more constraints than you can put after a `where` ... – Henk Holterman Sep 06 '17 at 13:06
  • @CShark: ask Erip Lippert, i haven't helped to create the compiler. But of course a compiler has more options than a C# developer using the .NET framework. – Tim Schmelter Sep 06 '17 at 13:07