20

Possible Duplicate:
Nullable type as a generic parameter possible?

I came across a very weird thing with generic type constraints. I have a class like this:

public SomeClass<T> where T:class
{
}

However, I've found I can't use nullable types as I'd expect:

new SomeClass<int?>();

I get an error that int? must be a reference type. Is Nullable really just a struct with syntactic sugar to make it look like a reference type?

Community
  • 1
  • 1
Earlz
  • 62,085
  • 98
  • 303
  • 499
  • 2
    What is the reason for that constraint? Can you provide more context? FYI Nullable is declared as: `public struct Nullable where T : struct` – Simon Whitehead Dec 10 '12 at 03:24
  • @SimonWhitehead basically because using value types on this class can have unexpected behavior and big performance impacts – Earlz Dec 10 '12 at 03:25
  • 1
    Then I guess the straight up answer is "yes, Nullable is a struct". I'm not quite sure what you consider to be syntactic sugar for Nullable. It would appear your only option is to roll your own. – Simon Whitehead Dec 10 '12 at 03:28
  • @SimonWhitehead well you can do `int? x = null`, but you can't do that with any other value type.. so I need a restriction to something like `where T:class, T:Nullable`, but that doesn't seem to work – Earlz Dec 10 '12 at 03:29
  • Well, as far as I remember, the CLR actually has an intimate understanding of the Nullable type. So this would explain why the C# compiler allows null to be assigned to a value type. – Simon Whitehead Dec 10 '12 at 03:45
  • 2
    There is simply an implicit conversion between `null` and any `Nullable` value. It doesn't actually store null, it just has a boolean `HasValue` and assigning null to it results in that being false and the actual `Value` property being...anything. This means that putting a value into a nullable struct doesn't actually box it or result in it gaining reference semantics. This does need special compiler support as there's no way to have a custom type with an implicity conversion for a struct from `null` while also not allowing any actual objects to be converted with it. – Servy Dec 10 '12 at 04:15

1 Answers1

22

Nullable<T> is a struct (see MSDN) however it is the only struct that does not satisfy the struct constraint. Therefore, you cannot use a Nullable as a generic type parameter when either the class or struct constraints is used.

Nullable<T> is not just a struct with some syntatic sugar. It has special support in the CLR for some of its behavior. For example, it has special boxing behavior. Specifically, a nullable is never boxed. The underlying value is boxed. If the nullable is the null value (HasValue is false) then it is converted to a null reference. Also, conversion operators for any Nullable<T> to Nullable<U> are lifted from the conversions from T to U. These are features you wouldn't be able to implement yourself in .NET 1.0/1.1.

Mike Zboray
  • 39,828
  • 3
  • 90
  • 122