it-swarm-ru.tech

Условное присвоение оператора с Nullable типами <value>?

EmployeeNumber =
string.IsNullOrEmpty(employeeNumberTextBox.Text)
    ? null
    : Convert.ToInt32(employeeNumberTextBox.Text),

Мне часто хочется сделать что-то подобное (EmployeeNumber - это Nullable<int>, поскольку это свойство объекта dbml LINQ-to-SQL, где столбец допускает значения NULL). К сожалению, компилятор считает, что "не существует неявного преобразования между" null "и" int "", даже если оба типа были бы допустимы в операции присваивания для обнуляемого int самостоятельно.

Насколько я могу судить, оператор объединения с нулевым значением не является опцией из-за встроенного преобразования, которое должно происходить со строкой .Text, если оно не равно нулю.

Насколько я знаю, единственный способ сделать это - использовать оператор if и/или назначить его в два этапа. В этом конкретном случае я нахожу это очень расстраивающим, потому что я хотел использовать синтаксис инициализатора объекта, и это назначение было бы в блоке инициализации ...

Кто-нибудь знает более элегантное решение?

57
Grank

Проблема возникает из-за того, что условный оператор не смотрит, как значение используется (назначается в этом случае) для определения типа выражения - только значения true/false. В этом случае у вас есть null и Int32, и тип не может быть определен (есть реальные причины его не могу просто предположить Nullable <Int32>).

Если вы действительно хотите использовать его таким образом, вы должны привести одно из значений к Nullable <Int32>, чтобы C # мог разрешить тип:

EmployeeNumber =
    string.IsNullOrEmpty(employeeNumberTextBox.Text)
    ? (int?)null
    : Convert.ToInt32(employeeNumberTextBox.Text),

или же

EmployeeNumber =
    string.IsNullOrEmpty(employeeNumberTextBox.Text)
    ? null
    : (int?)Convert.ToInt32(employeeNumberTextBox.Text),
65
Alex Lyman

Я думаю, что полезный метод может помочь сделать это чище.

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);
8
NerdFury

Хотя Алекс дает правильный и проксимальный ответ на ваш вопрос, я предпочитаю использовать TryParse:

int value;
int? EmployeeNumber = int.TryParse(employeeNumberTextBox.Text, out value)
    ? (int?)value
    : null;

Это безопаснее и заботится о случаях неправильного ввода, а также о вашем сценарии с пустой строкой. В противном случае, если пользователь введет что-то вроде 1b, ему будет представлена ​​страница с ошибкой с необработанным исключением, вызванным в Convert.ToInt32(string).

6
user13493

Вы можете разыграть вывод Convert:

EmployeeNumber = string.IsNullOrEmpty(employeeNumberTextBox.Text)
   ? null
   : (int?)Convert.ToInt32(employeeNumberTextBox.Text)
3
Abe Heidebrecht
//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;

Правка: краткое объяснение выше, я пытался получить значение Posid (если его ненулевое int и значение больше 0) в varibale X1. Мне пришлось использовать (int?) для Posid.Value, чтобы условный оператор не выдавал ошибку компиляции. Просто FYI GetHolidayCount - это метод WCF, который может дать null или любое число. надеюсь, это поможет

1
Sandeep