Why does Nullable<T> not match as a reference type for generic constraints [duplicate]
Asked Answered
G

1

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?

Gargantua answered 10/12, 2012 at 3:20 Comment(6)
What is the reason for that constraint? Can you provide more context? FYI Nullable is declared as: public struct Nullable<T> where T : structPhysicality
@SimonWhitehead basically because using value types on this class can have unexpected behavior and big performance impactsGargantua
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.Physicality
@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 workGargantua
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.Physicality
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.Aunt
G
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.

Galeiform answered 10/12, 2012 at 3:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.