Вопрос полиморфизма новичка с использованием дженериков - PullRequest
5 голосов
/ 23 февраля 2010

У меня есть следующий метод, который получает подробный объект, проверяет его, преобразует в запрос и ставит в очередь. Все хорошо, кроме запроса на подтверждение, с которым у меня возникли проблемы. По сути, существует разная логика проверки для каждого отдельного объекта сведений. Из общего ограничения я знаю, что у объекта деталей должен быть базовый класс BaseDetails, а из фактического общего параметра я знаю точный производный тип, но не знаю, как их использовать для написания моего класса валидатора, чтобы он обрабатывал все типы деталей :

private void Enqueue<TDetails, TRequest>(TDetails details)  
   where TDetails: BaseDetails where TRequest: BaseRequest
{
  bool isValid = _validator.Validate(details);

  if (isValid)
  {
    TRequest request = ObjectMapper
      .CreateMappedMessage<TDetails, TRequest>(details);

    _queue.Enqueue(request);
  }
}

Ответы [ 4 ]

2 голосов
/ 23 февраля 2010

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

1 голос
/ 23 февраля 2010

Из общего ограничения я знаю, что у объекта деталей должен быть базовый класс BaseDetails

Это известно в процессе компиляции в байт-код (я имею в виду, Visual Studio это знает)

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

Но это известно только после JIT-компиляции (Visual Studio ничего об этом не знает). Это как поздний переплет.

Поэтому, если вы хотите написать один класс валидатора с несколькими методами с разными типами аргументов, вы не сможете этого сделать, потому что компилятор Visual Studio не знал (во время компиляции), какой метод будет вызван.

Я считаю, что нет способов пропустить написание логики 'switch (typeof (TDetails)) ", где валидатор должен быть выбран TDetails. Так что вы должны написать какую-то фабрику, как Сэм Холдер писал выше.

PS: простите за мой английский. Я использую stackoverflow также для изучения английского языка:)

1 голос
/ 23 февраля 2010

Мне кажется, что логика проверки должна быть привязана к деталям самих объектов (если это возможно, конечно). Затем вы можете пометить абстрактный базовый класс и переопределить метод Validate для определенных классов деталей, если это необходимо.

С другой стороны, «составление наследства» в настоящее время модно.

0 голосов
/ 23 февраля 2010

Я думаю, вам нужно создать класс валидатора для каждой реализации TDetails, который знает, как проверять эту конкретную реализацию, а затем иметь фабрику для создания правильного валидатора для данной реализации TDetails, и ваш _validator должен получить правильный класс для выполнения. работа с завода и получить класс для проверки.

Очевидно, что вы можете иметь некоторые общие проверки в базовом классе.

Возможно, вам лучше иметь валидацию для самого объекта, а не создавать отдельный валидатор для каждой реализации TDetails ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...