Правильная обработка инициализации в обобщенных c методах - PullRequest
0 голосов
/ 14 февраля 2020

Предположим, у меня есть объект некоторого типа A и я хочу преобразовать его в тип B. Скажем, будет несколько реализаций этого интерфейса, так как у нас будет много дочерних элементов A и B. Итак, я создаю интерфейс наподобие:

interface IAToB {
    B Transform<A, B>(A a);
}

Проблема с этим интерфейсом, который я вижу, заключается в том, что мне нужно инициализировать объект типа B в Transform, что означает, что если я изменяю logi инициализации c из B, мне нужно соответствующим образом изменить все реализации IAToB. Итак, рассмотрим следующее:

interface IAToB {
    void Transform<A, B>(A a, out B b);
}

От разработчика IAToB теперь требуется передать инициализированный B.

Итак, последний интерфейс более совместим с принципами SOLID по сравнению к прежнему? Или я просто перемещаю соединение, фактически не уменьшая его, так сказать? Кроме того, имело ли бы смысл помещать дженерики в определение интерфейса, чтобы иметь interface IAToB<A, B> { ... }?

1 Ответ

1 голос
/ 14 февраля 2020

"Разработчик IAToB теперь обязан передавать инициализированный B. Итак, последний интерфейс более совместим с принципами SOLID по сравнению с прежним"

Первое утверждение здесь не соответствует действительности. Параметр out гарантированно инициализируется вызываемым методом, и не требуется, чтобы он был предварительно инициализирован для чего-либо (это на самом деле является избыточным и его следует избегать). Это только ссылка, к которой вызывающий может получить доступ после завершения метода. Поэтому ответ: «Нет, это не больше SOLID, чем в первом примере.»

Начиная с документация :

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

Обычно используется параметр out, чтобы метод мог возвращать более одного результата. TryParse является типичным примером, в котором он возвращает bool, указывающий на успех, и устанавливает параметр out в проанализированное значение (или значение по умолчанию для типа, если оно не удалось).


Кроме того, независимо от того, как вы реализуете этот метод преобразования, если вы измените logil инициализации c таким образом, который влияет на то, как B может быть создан из A, то вам придется обновить код преобразования где-то .

...