Неявное преобразование из Nullable в нормальное, есть идеи? - PullRequest
5 голосов
/ 26 апреля 2011

Я хочу получить представление о том, как неявно конвертировать nullable "?" переменные для районных.

данный пример

int? x = 5;

int y = x; //this gonna fail, !!!

Мне нужен какой-то способ переопределить параметр =, но, к сожалению, параметр = не перегружается ... любые предложения

Я использую C #

Ответы [ 4 ]

12 голосов
/ 26 апреля 2011

У вас есть два варианта, получить доступ к значению напрямую (если вы точно знаете, что оно не равно нулю):

int y = x.Value;

или используйте оператор объединения нулей:

int y = x ?? 0; // 0 if null...
7 голосов
/ 26 апреля 2011

Возможно реализовать неявный оператор приведения , но только для определенных вами типов или из них. Например, делать что-то вроде этого ..

public class NullableExtensions 
{
    public static implicit operator int(int? value)
    {
        return value ?? default(int);
    }
}

.. вернет CS0556 ошибку компиляции, потому что приведение не включает определенный пользователем тип.

Самое близкое, что вы можете сделать, это определить свой собственный тип Nullable, который содержит неявный оператор приведения:

public struct ImplicitNullable<T> where T: struct
{
    public bool HasValue { get { return this._value.HasValue; } }
    public T Value { get { return this._value.Value; } }

    public ImplicitNullable(T value) : this() { this._value = value; }
    public ImplicitNullable(Nullable<T> value) : this() { this._value = value; }

    public static implicit operator ImplicitNullable<T>(T value) { return new ImplicitNullable<T>(value); }
    public static implicit operator ImplicitNullable<T>(Nullable<T> value) { return new ImplicitNullable<T>(value); }

    public static implicit operator T(ImplicitNullable<T> value) { return value._value ?? default(T); }
    public static implicit operator Nullable<T>(ImplicitNullable<T> value) { return value._value; }

    private Nullable<T> _value { get; set; }

    // Should define other Nullable<T> members, especially 
    // Equals and GetHashCode to avoid boxing
}

Обратите внимание, что хотя этот код можно написать, он, вероятно, приведет к трудным отслеживанию ошибок. Я бы порекомендовал использовать явное приведение или генерировать исключение при значении null.

После этого вы можете кастовать в и из ожидаемого:

static void Main()
{
    int myInt = 1;
    int? nullableInt = 2;

    ImplicitNullable<int> implicitInt;

    // Convert from int or int?
    implicitInt = myInt;
    implicitInt = nullableInt;

    // Convert to int or int?
    myInt = implicitInt;
    nullableInt = implicitInt;
}
3 голосов
/ 26 апреля 2011

Подождите, я так растерялся ...

Почему бы вам просто не использовать GetValueOrDefault ?

1 голос
/ 26 апреля 2011

Я предполагаю, что это C # .

Вам нужно либо разыграть, либо использовать .value:

 int? x = 5;
 int y;

 if(x.HasValue)
     y = x.Value;
 else
     throw new//... handle error or something
...