2014-10-10 10 views
0

У меня есть следующий код, который, как я считаю, не работает должным образом, и я не могу понять, почему.VB Одиночная строка с нулевыми значениями

dim total as decimal? = If(first Is Nothing OrElse second Is Nothing, _ 
          Nothing, _ 
          Math.Abs(If(first, 0D)) - Math.Abs(If(second, 0D))) 

Если либо первый или второй не ничего, то ничего не должно быть помещено в total. Однако, если оба они имеют значения, они должны быть изменены на положительные значения, и необходимо вычислить first - second. Первый и второй являются значениями с нулевым числом (десятичным?).

Ожидаемые результаты:

first = nothing 
second = nothing 
total = nothing 

Фактические результаты:

first = nothing 
second = nothing 
total = 0D 

Я не могу понять, почему если оператор не прыгает к истинному сегменту и не поставив ничего в переменную общего

ответ

0

Я вернусь, чтобы сделать расширение компилятора, которое позволяет выполнять функцию абсолютного значения с нулевым десятичным числом, возвращая значение, если оно ничего или неотрицательное, иначе умножьте на -1 и верните. Таким образом, если он ничего не возвращает, результат вычисления будет таким, как ожидалось.

dim total as decimal? = first.ToAbsoluteValue() - second.ToAbsoluteValue()

<System.Runtime.CompilerServices.Extension()> Friend Function ToAbsoluteValue(value As Decimal?) As Decimal? If value Is Nothing OrElse value >= 0 Then Return value Return Math.Abs(If(value, 0D)) End Function

Если кто-нибудь знает, как добавить это к Math.abs() перегружает, что было бы гораздо чище вариант.

2

If() оператор строго типизирован, но компилятор должен вывести тип результата на основе входов.

В этом случае он не может определить тип из первого варианта (Nothing), потому что ничего само по себе не имеет типа, и в отличие от С # null, Ничто не может свести к типу значения (это будет иметь важное значение в момент). Поэтому компилятор должен посмотреть на второй вариант: Math.Abs(If(first, 0D)) - Math.Abs(If(second, 0D)). Тип этого выражения оценивается как Decimal ... не a Decimal?. Следовательно, итоговый тип вашего всего выражения If() - это Decimal, а не Decimal?. То, что вы назначаете результат Decimal?, не имеет значения.

Я не могу понять, почему, если оператор не прыгает к истинному сегменту и не поставив ничего в переменную общего

Это именно то, что он делает. Однако, как упоминалось ранее, Nothing в VB.Net может быть присвоен типам значений. До того, как может произойти назначение, ничто не преобразуется в десятичное число, потому что это результат типа этого выражения If(). В случае Десятичного числа присваивание значения Nothing приводит к десятичному значению по умолчанию 0D ... следовательно, к вашим результатам.

Я не тестировал это, но думаю, что вы можете исправить это, чтобы получить желаемые результаты, явно наведя выражение False в вашем If() оператором как Decimal?/Nullable(Of Decimal). Это скажет компилятору вывести Decimal? вместо Decimal для типа выражения If(), и поэтому возврат Nothing из этого выражения будет иметь желаемый результат.

+0

вам не разрешено передавать значения NULL в Math.Abs ​​() – theB3RV

+0

Хм ... полезно знать. Раньше не сталкивался с этим. Я отредактирую свой ответ. –

+0

, потому что ложная часть никогда не приведет ни к чему ... отсюда причина проверки предварительного условия – theB3RV

Смежные вопросы