Условное назначение оператора с помощью типов Nullable <value>?
EmployeeNumber =
string.IsNullOrEmpty(employeeNumberTextBox.Text)
? null
: Convert.ToInt32(employeeNumberTextBox.Text),
Я часто нахожу, что хочу делать что-то вроде этого (EmployeeNumber
является Nullable<int>
, поскольку он является свойством в объекте dbml LINQ to SQL, где столбец допускает значения NULL). К сожалению, компилятор считает, что "нет никакого неявного преобразования между" null "и" int ", хотя оба типа были бы действительны в операции присваивания с помощью NULL int.
Оператор Null coalescing не является опцией, насколько я могу видеть из-за встроенного преобразования, которое должно произойти в строке .Text, если оно не равно null.
Насколько я знаю, единственный способ сделать это - использовать оператор if и/или назначить его в два этапа. В этом конкретном случае я нахожу это очень расстраивающим, потому что я хотел использовать синтаксис инициализатора объекта, и это назначение было бы в блоке инициализации...
Кто-нибудь знает более элегантное решение?
Ответы
Ответ 1
Проблема возникает из-за того, что условный оператор не смотрит, как это значение используется (назначается в этом случае), чтобы определить тип выражения - только значения true/false. В этом случае у вас есть null и Int32, и тип не может быть определен (есть реальные причины, по которым он не может просто принять Nullable <Int32 > ).
Если вы действительно хотите использовать его таким образом, вы должны сделать одно из значений Nullable <Int32 > самостоятельно, поэтому С# может разрешить тип:
EmployeeNumber =
string.IsNullOrEmpty(employeeNumberTextBox.Text)
? (int?)null
: Convert.ToInt32(employeeNumberTextBox.Text),
или
EmployeeNumber =
string.IsNullOrEmpty(employeeNumberTextBox.Text)
? null
: (int?)Convert.ToInt32(employeeNumberTextBox.Text),
Ответ 2
Я думаю, что полезный метод может помочь сделать это чище.
public static class Convert
{
public static T? To<T>(string value, Converter<string, T> converter) where T: struct
{
return string.IsNullOrEmpty(value) ? null : (T?)converter(value);
}
}
затем
EmployeeNumber = Convert.To<int>(employeeNumberTextBox.Text, Int32.Parse);
Ответ 3
Пока Алекс дает правильный и проксимальный ответ на ваш вопрос, я предпочитаю использовать TryParse
:
int value;
int? EmployeeNumber = int.TryParse(employeeNumberTextBox.Text, out value)
? (int?)value
: null;
Это безопаснее и заботится о случаях недействительного ввода, а также о пустом сценарии. В противном случае, если пользователь вводит что-то вроде 1b
, им будет представлена страница с ошибкой с необработанным исключением, вызванным в Convert.ToInt32(string)
.
Ответ 4
Вы можете сделать вывод Convert:
EmployeeNumber = string.IsNullOrEmpty(employeeNumberTextBox.Text)
? null
: (int?)Convert.ToInt32(employeeNumberTextBox.Text)
Ответ 5
//Some operation to populate Posid.I am not interested in zero or null
int? Posid = SvcClient.GetHolidayCount(xDateFrom.Value.Date,xDateTo.Value.Date).Response;
var x1 = (Posid.HasValue && Posid.Value > 0) ? (int?)Posid.Value : null;
EDIT:
Краткое объяснение выше, я пытался получить значение Posid
(если его nonnull int
и имеет значение больше 0) в varibale X1
. Мне пришлось использовать (int?)
на Posid.Value
, чтобы оператор условного выражения не выдавал ошибку компиляции.
Просто FYI GetHolidayCount
- это метод WCF
, который может дать null
или любое число.
Надеюсь, что поможет