Подтвердить что ты не робот

Математические операции с нулевым

Пожалуйста, объясните, почему проходит этот тест?

[Test]
public void TestNullOps()
{
    Assert.That(10 / null, Is.Null);
    Assert.That(10 * null, Is.Null);
    Assert.That(10 + null, Is.Null);
    Assert.That(10 - null, Is.Null);
    Assert.That(10 % null, Is.Null);
    Assert.That(null / 10, Is.Null);
    Assert.That(null * 10, Is.Null);
    Assert.That(null + 10, Is.Null);
    Assert.That(null - 10, Is.Null);
    Assert.That(null % 10, Is.Null);

    int zero = 0;
    Assert.That(null / zero, Is.Null);
}

Я не понимаю, как этот код даже компилируется.

Похоже, каждое математическое выражение с нулевым возвратом Nullable<T> (например, 10 / null является Nullable<int>). Но я не вижу операторных методов в классе Nullable<T>. Если эти операторы взяты из int, почему последнее утверждение не терпит неудачу?

4b9b3361

Ответ 1

От MSDN:

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

Итак, почему все тесты пройдены, включая последний, независимо от значения операнда, если другой операнд null, тогда результат будет null.

Ответ 2

Операторы для Nullable<T> являются так называемыми "поднятыми" операторами]; компилятор С# принимает операторы, доступные для T, и применяет набор предопределенных правил; например, с +, поднятый + равен null, если один из операндов равен null, иначе сумма внутренних значений. Повторить последнее; снова, деление определяется как null, если либо операнд null - он никогда не выполняет деление.

Ответ 3

Я бы предположил, что компилятор преобразует zero в Nullable<int> и предоставляет базовый оператор разделения. Так как тип Nullable может быть нулевым, деление на 0 не происходит во время компиляции. Лучше всего предположить, что они хотят, чтобы вы могли выполнять нулевое тестирование в случаях, когда происходит div/0.

Ответ 4

Я попытался увидеть сгенерированный код из приведенного ниже кода с помощью рефлектора

var myValue = 10 / null;

И компилятор превращает его в это:

int? myValue = null;

И это не скомпилируется, поэтому вы не можете его обмануть:

object myNull = null;
var myValue = 10 / myNull;

Ответ 5

Операции в этом списке всегда возвращают NULL:

1 + 2 + 3 + NULL

5 * NULL - 7

'Home ' || 'sweet ' || NULL

MyField = NULL

MyField <> NULL

NULL = NULL