Почему я не могу присвоить значение null десятичной дроби с тройным оператором?

Я не понимаю, почему это не сработает

decimal? compRetAmount = !string.IsNullOrEmpty(txtLineCompRetAmt.Text) 
    ? decimal.Parse(txtLineCompRetAmt.Text.Replace(",","")) 
    : null;

Ответ 1

Потому что null имеет тип object (фактически нетипированный), и вам нужно назначить его типизированному объекту.

Это должно работать:

decimal? compRetAmount = !string.IsNullOrEmpty(txtLineCompRetAmt.Text) 
         ? decimal.Parse(txtLineCompRetAmt.Text.Replace(",","")) 
         : (decimal?)null;

или это немного лучше:

decimal? compRetAmount = !string.IsNullOrEmpty(txtLineCompRetAmt.Text) 
         ? decimal.Parse(txtLineCompRetAmt.Text.Replace(",","")) 
         : default(decimal?);

Вот ссылка MSDN для default.

Ответ 2

Не используйте decimal.Parse.

Convert.ToDecimal вернет 0, если ему задана пустая строка. decimal.Parse будет генерировать ArgumentNullException, если строка, которую вы хотите проанализировать, имеет значение null.

Ответ 3

Попробуйте следующее:

decimal? compRetAmount = !string.IsNullOrEmpty(txtLineCompRetAmt.Text) ? 
                         decimal.Parse(txtLineCompRetAmt.Text.Replace(",", "")) : 
                         (decimal?) null;

Проблема заключается в том, что компилятор не знает, какой тип null имеет. Поэтому вы можете просто направить его на decimal?

Ответ 4

decimal? compRetAmount = !string.IsNullOrEmpty(txtLineCompRetAmt.Text) ?  
                          decimal.Parse(txtLineCompRetAmt.Text.Replace(",","")) : 
                          (decimal?)null;

Ответ 5

Поскольку компилятор не может вывести лучший тип из операндов условного оператора.

Когда вы пишете condition ? a : b, должно быть неявное преобразование из типа a в тип b или из типа b в тип a. Затем компилятор выводит тип всего выражения в качестве целевого типа этого преобразования. Тот факт, что вы назначаете его переменной типа decimal?, никогда не рассматривается компилятором. В вашем случае типы a и b являются decimal и неизвестным типом ссылки или типа NULL. Компилятор не может догадаться, что вы имеете в виду, поэтому вам нужно помочь:

decimal? compRetAmount = !string.IsNullOrEmpty(txtLineCompRetAmt.Text)
                             ? decimal.Parse(txtLineCompRetAmt.Text.Replace(",",""))
                             : default(decimal?);

Ответ 6

Вам нужно передать первую часть в decimal?

decimal? compRetAmount = !string.IsNullOrEmpty(txtLineCompRetAmt.Text) 
    ? (decimal?)decimal.Parse(txtLineCompRetAmt.Text.Replace(",","")) 
    : null;