Условное присвоение оператора с типами Nullable <value>? - PullRequest
56 голосов
/ 16 сентября 2008
EmployeeNumber =
string.IsNullOrEmpty(employeeNumberTextBox.Text)
    ? null
    : Convert.ToInt32(employeeNumberTextBox.Text),

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

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

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

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

Ответы [ 5 ]

65 голосов
/ 16 сентября 2008

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

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

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

или

EmployeeNumber =
    string.IsNullOrEmpty(employeeNumberTextBox.Text)
    ? null
    : (int?)Convert.ToInt32(employeeNumberTextBox.Text),
8 голосов
/ 16 сентября 2008

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

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);
6 голосов
/ 16 сентября 2008

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

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

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

3 голосов
/ 16 сентября 2008

Вы можете разыграть вывод Преобразования:

EmployeeNumber = string.IsNullOrEmpty(employeeNumberTextBox.Text)
   ? null
   : (int?)Convert.ToInt32(employeeNumberTextBox.Text)
1 голос
/ 24 апреля 2015
//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 (если оно не равно int и имеет значение больше 0) в переменной X1. Мне пришлось использовать (int?) на Posid.Value, чтобы условный оператор не выдавал ошибку компиляции. Просто FYI GetHolidayCount - это метод WCF, который может дать null или любое число. Надеюсь, что это поможет

...