Подтвердить что ты не робот

Как работает тип Nullable <T> за кулисами?

Мне любопытно узнать, как работает Nullable типа за кулисами. Является ли это создание нового объекта (объектам может быть присвоено значение null) с возможным значением null?

В примере мы используем Nullable <int> , это их какое-то неявное преобразование из объекта в int и наоборот, когда вы присваиваете ему нулевое значение?

Также я знаю, как это можно создать вручную, есть ли возможность использовать тип Nullable в отличие от его создания?

4b9b3361

Ответ 1

Тип с нулевым значением - это структура, состоящая из двух полей: a bool и a T. Когда значение равно null, bool является ложным, а значение T имеет значение по умолчанию. Если значение не равно null, значение bool равно true.

Существует два основных преимущества использования Nullable по сравнению с реализацией самой функции. Там поддерживается языковая поддержка, как описано более подробно в ChaosPandion, и есть тот факт, что бокс (преобразование в object) автоматически удаляет обнуляемую "обертку" с нулевым значением, оставляя либо нулевую ссылку, либо простой T object.z

Ответ 2

Вот код (приведенный) от запуска .Net Reflector против 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;
}
}

Ответ 3

На самом деле это довольно просто. Компилятор дает вам руку с синтаксисом.

// 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;

Ответ 4

Nullable<T> реализуется как структура, которая переопределяет Equals(), чтобы вести себя как null, если HasValue - false. Существует неявное преобразование из T в T? и явное преобразование в другом направлении, которое выдает, если !HasValue.