11

According to the docs: http://msdn.microsoft.com/en-us/library/x13ttww7.aspx:

The volatile keyword can be applied to reference types.

So why is it illegal to use on a Nullable<T>.. a reference type!

Please note that I do not actually need volatile semantics on a Nullable<T> field, I encountered this error accidentally and am simply curious.

Tergiver
  • 14,171
  • 3
  • 41
  • 68

2 Answers2

14

Nullable<T> isn't a reference type. It's a value type:

public struct Nullable<T>
where T : struct, new()

Note the struct part.

Just because it has a null value doesn't make it a reference type... it's a nullable value type. See section 4.1.10 of the C# 4 language spec for more details.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Of course it's physically impossible to represent a value type with null, so while I will accept that the language defines it as 'struct' (and therefore cannot be volatile), I will not accept that it's actually a value type =) – Tergiver Nov 18 '11 at 23:49
  • 3
    @Tergiver: You've misunderstood `null`. `Nullable` very definitely *is* a value type, but `null` doesn't mean what you think it means. The `null` literal is convertible to "the null value for any nullable type" - a null *reference* for reference types, or a value where the `HasValue` property is false for a nullable value type. – Jon Skeet Nov 18 '11 at 23:52
  • No I understand perfectly. Your speaking in the strict sense of the (high-level) language. I tend to think at a lower level. I'm not arguing that you're wrong. You are very much correct. – Tergiver Nov 18 '11 at 23:54
  • 2
    @Tergiver: No, I'm speaking at *every* level. `Nullable` *is* a value type, plain and simple. It's as much a value type as `Guid`. If you think of it as a reference type, you *are* misunderstanding it. – Jon Skeet Nov 18 '11 at 23:55
  • Imagine you are a 32-bit microprocessor and you have a 32-bit integer with a range of [0..2^32-1]. How are you going to represent one more possible value (null)? You cannot. Nullable is strictly a language feature. How it gets implemented is where I was thinking of it as a reference type. You're right, that's a misunderstanding. – Tergiver Nov 19 '11 at 00:00
  • 2
    @Tergiver: You store it as a 32-bit value *and* a single bit... which are stored together as a value in the same way that multiple fields are encapsulated in other value types. The value of a nullable value type variable is *not* a reference, it's all of the information about a that value. When you use the assignment operator, that creates a copy of both the value and the "is this a real value" Boolean. It's *not* just a language feature - it requires support in the language, the framework *and* the CLR. It's very much a value type *even in implementation*. – Jon Skeet Nov 19 '11 at 00:04
  • Then I am indeed wrong at every level! Thanks Jon. I'm happy to learn from my mistake. – Tergiver Nov 19 '11 at 00:12
  • @JonSkeet: I think by "a single bit" you mean "a single byte + 3 alignment bytes"? :P – user541686 Nov 20 '11 at 10:17
  • @Mehrdad: Well, it's logically storing a single bit - which is then "stored together as a value in the same way that multiple fields are encapsulated in other value types" :) – Jon Skeet Nov 20 '11 at 12:16
  • I don't know where I got the idea that `Nullable`'s were always boxed, but knowing they are "extended structures" is valuable performance information (where applicable of course). – Tergiver Nov 21 '11 at 17:02
4

Nullable is a value type, not a reference type.

See http://msdn.microsoft.com/en-us/library/b3h38hb0.aspx for definition.

Rich O'Kelly
  • 41,274
  • 9
  • 83
  • 114