Оператор, перегружающийся с основанным на интерфейсе программированием в C#

В JUnit5 вы можете запускать параметризованные тесты с CSV-источником . Вы можете увидеть пример со встроенными значениями CSV:

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

class PriceCalculatorTest {

  PriceCalculator classUnderTest;

  @BeforeEach
  void setUp() throws Exception {
    classUnderTest = new PriceCalculator();
  }

  @ParameterizedTest
  @CsvSource({"0.0, 13", "5.0, 14", "5.0,26", "15.0,27", "15.0,64", "10.0,65"})
  void testGetPrice(double expected, int age) {
    assertEquals(expected, classUnderTest.getPrice(age), 0.01D);
  }
}

Если вы хотите использовать внешний файл данных, для этого есть немного другой синтаксис:

@CsvFileSource(resources = "/two-column.csv", numLinesToSkip = 1)

используя CSV-файл с заголовками в первой строке. Если вы хотите использовать другой формат файла, вам нужно реализовать свой собственный ArgumentsProvider.

72
задан Zach Burlingame 8 April 2009 в 12:32
поделиться

1 ответ

Короткий ответ: Я думаю, что Ваше второе предположение может быть испорчено. Equals() правильный путь состоит в том, чтобы проверить на семантическое равенство двух объектов, нет operator ==.


Длинный ответ: разрешение Перегрузки для операторов выполняется во время компиляции, не время выполнения.

Если компилятор не может окончательно знать типы объектов, он применяет оператор к, он не скомпилирует. Так как компилятор не может быть уверен что IAddress будет чем-то, что имеет переопределение для == определенный, это отступает к значению по умолчанию operator == реализация System.Object.

Для наблюдения этого более ясно попытайтесь определить operator + для Address и добавление два IAddress экземпляры. Если Вы явно не бросаете к Address, это не скомпилирует. Почему? Поскольку компилятор не может сказать что деталь IAddress Address, и нет никакого значения по умолчанию operator + реализация для отступания к в System.Object.


Часть Вашего разочарования, вероятно, останавливает от факта это Object реализации operator ==, и все Object, таким образом, компилятор может успешно разрешить операции как a == b для всех типов. Когда Вы переопределили ==, Вы ожидали видеть то же поведение, но не сделали, и поэтому лучшее соответствие, которое может найти компилятор, является оригиналом Object реализация.

Требование, чтобы все сравнения использовали, Равняется, а не оператор == не является эффективным решением, особенно при передаче типов библиотекам (таким как Наборы).

По моему мнению, это точно, что необходимо делать. Equals() правильный путь состоит в том, чтобы проверить на семантическое равенство двух объектов. Иногда семантическое равенство является просто ссылочным равенством, в этом случае Вы ничего не должны будете изменять. В других случаях, как в Вашем примере, Вы переопределите Equals когда Вам нужен более сильный контракт равенства, чем ссылочное равенство. Например, можно хотеть рассмотреть два Persons равняйтесь, если у них есть тот же Номер социального страхования, или два Vehicles равняйтесь, если у них есть тот же VIN.

Но Equals() и operator == не то же самое. Каждый раз, когда необходимо переопределить operator ==, необходимо переопределить Equals(), но почти никогда наоборот. operator == больше синтаксического удобства. Некоторые языки CLR (например, Визуальный Basic.NET) даже не разрешают Вам переопределять оператор равенства.

57
ответ дан John Feminella 24 November 2019 в 12:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: