Вопрос о полиморфизме новичка с помощью дженериков

У меня есть следующий метод, который берет в объекте деталей, проверяет его, преобразовывает его в запрос и ставит в очередь его. Все прекрасно кроме проверить запроса, из-за которого я испытываю затруднения. В основном существует другая логика проверки для каждого различного объекта деталей. Я знаю от универсального ограничения, что объект деталей должен иметь базовый класс 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);
  }
}
5
задан Arnis Lapsa 23 February 2010 в 10:28
поделиться

4 ответа

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

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

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

0
ответ дан 15 December 2019 в 00:59
поделиться

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

2
ответ дан 15 December 2019 в 00:59
поделиться

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

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

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

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

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

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

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

1
ответ дан 15 December 2019 в 00:59
поделиться

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

С другой стороны, сейчас в моде «композиция важнее наследования».

1
ответ дан 15 December 2019 в 00:59
поделиться
Другие вопросы по тегам:

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