tags:

views:

533

answers:

6

Is there any penalty, such that you should only set them as nullable when you really need it?

Thanks

+1  A: 

Which value types are actually nullable? I know of none.

EDIT: If you refer to the string type, then it is not a value type, but a reference type.

User
You need to wrap them in the Nullable<T> type
Phil Nash
But that's something different then. I believe the topic starter meant value types nullable out of the box, probably referring to string type.
User
I think the OP means something like "if value types can be made nullable, why aren't they all nullable from start?".
Guffa
Well, lots of programmers cannot grasp the concepts of pointers and recursions, many would probably be confused if types were all nullable from the start. Nullable<T> is for advanced classes.
User
+5  A: 

Yes, there is a penalty. The Nullable<T> structure contain the value and also a boolean flag that determines the nullness of the value.

Although the boolean is only one byte, structures are aligned to even word boundaries. An int uses four bytes of memory, but an int? needs eight bytes.

Guffa
+17  A: 
Marc Gravell
Don't forget about the extra ?? operator they threw in as well.int i = j ?? k; // if j is null, use k.
Chris Brandsma
well, that isn't specific to `Nullable<T>` - but another good point
Marc Gravell
@Chris does that work at all? j can't be null, else you can't assign it to a value type, right? ;-)
Erik van Brakel
@Erik - it can if `j` is nullable (i.e. `int?`) and `k` is non-nullable (i.e. `int`)
Marc Gravell
And you will be screwed if you use ReferenceEquals!
leppie
@leppie - that stands for any (unboxed) value-type, though
Marc Gravell
+1 `Meaning` is the most important point I think!
Dario
A: 

In addition to Marc Gravell answer, check the reflected code from Nullable<T>:

public struct Nullable&lt;T&gt; where T: struct
{
    private bool hasValue;

    internal T value;

    public Nullable(T value)
    {
        this.value = value;
        this.hasValue = true;
    }

    public bool HasValue
    {
        get
        {
            return this.hasValue;
        }
    }
    public T Value
    {
        get
        {
            if (!this.HasValue)
            {
                ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NoValue);
            }
            return this.value;
        }
    }
    public T GetValueOrDefault()
    {
        return this.value;
    }

    public T GetValueOrDefault(T defaultValue)
    {
        if (!this.HasValue)
        {
            return defaultValue;
        }
        return this.value;
    }

    public override bool Equals(object other)
    {
        if (!this.HasValue)
        {
            return (other == null);
        }
        if (other == null)
        {
            return false;
        }
        return this.value.Equals(other);
    }

    public override int GetHashCode()
    {
        if (!this.HasValue)
        {
            return 0;
        }
        return this.value.GetHashCode();
    }

    public override string ToString()
    {
        if (!this.HasValue)
        {
            return "";
        }
        return this.value.ToString();
    }

    public static implicit operator T?(T value)
    {
        return new T?(value);
    }

    public static explicit operator T(T? value)
    {
        return value.Value;
    }
}

You'll notice the existence of the boolean HasValue and how the properties use it.

Fernando
A: 

Consider the implementation. An integer in C# is defined as

public struct Int32 : IComparable, IFormattable, IConvertible, IComparable<int>, IEquatable<int>

A struct is stored directly on the stack, as opposed to objects references which are pointers to memory (the reference itself is in the stack, but the allocation is in the stack).

A NULL reference simply means that the pointer in the stack hasn't been initialized to a location in the heap.

Babak Naffas
A: 

For using System.Nullable please refer Nullable type in C# brief details

bimbim.in