#c# #nullable #implicit-conversion
#c# #nullable #неявное преобразование
Вопрос:
Я хочу получить представление о том, как неявно преобразовать nullable переменные «?» в окружные.
учитывая этот пример
int? x = 5;
int y = x; //this gonna fail, !!!
мне нужен какой-то способ переопределить = parameter , но, к сожалению, параметр = нельзя перегрузить… есть предложения
Я использую C#
Комментарии:
1. На каком языке это? Или это не зависит от языка, и я не замечаю?
Ответ №1:
У вас есть два варианта: получить доступ к значению напрямую (если вы точно знаете, что оно не равно null):
int y = x.Value;
или используйте оператор объединения null:
int y = x ?? 0; // 0 if null...
Комментарии:
1. ну да, это верно, но мне нужно, чтобы это было сделано неявно, потому что есть много кода, использующего это.
2. @Mustafa — если ты придумаешь, как сделать это неявно, дай мне знать 😉 В C # вы не можете перегружать оператор присваивания. Вы также не можете расширять
int
. То, как вы решите эту проблему, будет зависеть от архитектуры вашего приложения. Можете ли вы пойти другим путем и заменить всеint
s наint?
s, посколькуint
это неявно преобразует вint?
?3. @Mustafa: Вы не можете переопределить оператор ‘=’, это не метод. Если бы вы сравнивали значения, используя
.Equals
метод, то вы могли бы написать переопределение для него.4. вы правы, я не могу расширить ‘int’ и не могу перегрузить оператор =, я думаю, у меня нет другого выбора, кроме как перепроектировать модель предметной области для использования правильных типов данных, приветствия.
5. также int y = x.Имеет значение ? x.Value : 0; //0, если null
Ответ №2:
Можно реализовать неявный оператор приведения, но только к определяемым вами типам или из них. Например, сделать что-то вроде этого..
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:
Подождите, я так запутался…
Почему бы вам просто не использовать GetValueOrDefault?
Комментарии:
1. Потому что у меня уже есть написанный код, и я не хочу передавать его, набирая после каждого prop «GetValueOrDefault()», спасибо
Ответ №4:
Я предполагаю, что это C #.
Вам нужно либо привести, либо использовать .value
:
int? x = 5;
int y;
if(x.HasValue)
y = x.Value;
else
throw new//... handle error or something