tags:

views:

402

answers:

4

I was having a conversation with a co-worker and the subject of null came up. He was telling me that in .NET behind the scenes it is just a really small number. I always thought that the object just didn't have a pointer to any memory on the heap but i wasn't sure either way.

So i'm hoping the community can clear it up for us ;P

A: 

from my experience, I believe Nothing will work, and so will DBNull.Value

Sukasa
...And I just completely misunderstood it. I believe Null or 'Nothing' is numerically equivalent to Zero, and stored as whatever data type the variable it is assigned to it
Sukasa
Probably best just to delete the answer, else you will get down votes :) +1 for honesty
leppie
And now you see the difference between == and ===, try comparing these various null types.
TravisO
+13  A: 

It's 0.

Snip from ldnull in ECMA-335 spec:

It might be thought that ldnull is redundant: why not use ldc.i4.0 or ldc.i8.0 instead? The answer is that ldnull provides a size-agnostic null – analogous to an ldc.i instruction, which does not exist. However, even if CIL were to include an ldc.i instruction it would still benefit verification algorithms to retain the ldnull instruction because it makes type tracking easier.

leppie
I really have to disagree that null is 0... 0 is a value... null is a placeholder for the absence of a reference to an object. To initialize an object to be null and then say "oh, it's also equal to the value 0" is a little contradictory in my opinion
lomaxx
@lomaxx - it really is zero; that's the way it's implemented at CIL level. You can think of it as being a special memory address which is interpreted as null.
Greg Beech
@lomaxx: null is definitely a value. You can do everything with it that you can with another value - pass it, assign it to a variable etc. Its *bitwise representation* is all zeroes.
Jon Skeet
A: 

From MSDN:

The null keyword is a literal that represents a null reference, one that does not refer to any object

To try and make it a little clearer in the older versions of c#, a value type couldn't be null, ie, it HAD to have a value, if you didn't assign one, you got a potentially random value so something like:

int i;
i++;
console.writeline(i);

in the older versions of c# objects had to be initialized otherwise they were null, which meant they had no reference to any object.

Now with nullable value types in c# 2.0+ you can have a nullable int which means that if you have this code:

int? i;
i++;
console.writeline(i);

you will actually get an exception at i++ because i has never been initialized to anything other than null. If null was 0, this code would execute fine because it'd just evaluate to 0+1, however this is incorrect behaviour.

If null was always 0 and you had a a nullable int, and you wrote some code like:

int? i;
if (int == 0)
{
//do something
}

there is a very real possibility you could get some unexpected behaviour IF null was the same as 0 because there is no way the compiler could differentiate between the int being null and the int being explicitly set to 0.

Another example that clarifies things in my mind:

public int? AddNumbers(int? x, int? y)
{
    if (x == null || y == null)
        return null;
    if (x == 0)
        return y;
    if (y == 0)
        return x;

    return x + y;
}

in this example, it's clear that null and 0 are very different because if you were to pass in 0 for x or y, and null was equal to 0, then the code above would never get to the checks for x == 0 or y == 0, however if you run the code and pass in 0 for x or y, the checks do get executed.

lomaxx
I don't think this helps. The behaviour of lifted operators has little to do with the underlying value of null. And as it happens, the binary value of a "null" Nullable<T> *is* zero. All zeros. So for int? it is 5 zeros (one for the bool flag, 4 for the int).
Marc Gravell
(note, the -1 isn't from me; I prefer to feed back via comments - not just down-vote blindly)
Marc Gravell
but if the value of null *is* zero, then what is the value of zero? how do you differentiate between the two?
lomaxx
Nullable<T> is treated specially by both the CLR and the C# language to make it appear that it is a true null. It isn't really; it's just a compiler trick that lets you write "x == null" rather than "!x.HasValue", because Nullable<T> is a value type itself so can't really be null.
Greg Beech
lomaxx, a nullable type is a structure that combines a value of the underlying type with a boolean null indicator. If the type is set to a value of null, that means its underlying value is zero and its null indicator is set to true.
RoadWarrior
RoadWarrior... that's probably the best explanation of "How is null represented".
lomaxx
I guess there's 3 ways of asking this question: What is the underlying value of null? What is the (face) value of null? and What structure is used to represent null? I was trying to answer the second where as others were trying to answer other variations so that's probably where the confusion arose
lomaxx
+5  A: 

When a nullable type instance is set to null, its underlying value is zero.

To be more specific, a nullable type is a structure that combines a value of the underlying type together with a boolean null indicator. An instance of a nullable type has two public read-only properties: HasValue of type bool, and Value of the nullable type’s underlying type.

HasValue is true for a non-null instance and false for a null instance.

So when HasValue is true, the Value property returns the contained value. When HasValue is false, an attempt to access the Value property throws an exception. But if you could access it, you would find it contains zero.

RoadWarrior
Awesome this is exactly what i'm looking for.
Alex