How does a Nullable type work behind the scenes?

后端 未结 4 1938
一个人的身影
一个人的身影 2020-12-15 08:41

I\'m curious to know how the Nullable type works behind the scenes. Is it creating a new object(objects can be assigned null) with a possible value of null?

In the

相关标签:
4条回答
  • 2020-12-15 09:07

    The nullable type is a struct consisting of two fields: a bool and a T. When the value is null, the bool is false and the T has the default value. When the value is not null, the bool is true.

    There are two main benefits to using Nullable as compared to implementing the functionality yourself. There's the language support, as described in more detail in ChaosPandion's answer, and there's the fact that boxing (converting to an object) will automatically remove the nullable "wrapper", leaving either a null reference or the plain T object.z

    0 讨论(0)
  • 2020-12-15 09:13

    It's actually quite simple. The compiler gives you a hand with the syntax.

    // this
    int? x = null;
    // Transformed to this
    int? x = new Nullable<int>()
    
    // this
    if (x == null) return;
    // Transformed to this
    if (!x.HasValue) return;
    
    // this
    if (x == 2) return;
    // Transformed to this
    if (x.GetValueOrDefault() == 2 && x.HasValue) return;
    
    0 讨论(0)
  • 2020-12-15 09:15

    Here is the (tidied up) code from running .Net Reflector against Nullable...

    [Serializable, StructLayout(LayoutKind.Sequential), TypeDependency("System.Collections.Generic.NullableComparer`1"), TypeDependency("System.Collections.Generic.NullableEqualityComparer`1")]
    public struct Nullable<T> 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 Nullable<T>(T value)
    {
        return new Nullable<T>(value);
    }
    
    public static explicit operator T(Nullable<T> value)
    {
        return value.Value;
    }
    }
    
    0 讨论(0)
  • 2020-12-15 09:28

    Nullable<T> is implemented as a struct that overrides Equals() to behave as null if HasValue is false. There is an implicit conversion from T to T?, and an explicit conversion in the other direction which throws if !HasValue.

    0 讨论(0)
提交回复
热议问题