Использование шаблона стратегии для обработки различных типов сообщений - PullRequest
0 голосов
/ 28 февраля 2020

У меня есть файл журнала с несколькими типами сообщений. Каждый тип сообщения различается по тегу 35. Например, тег 35 может быть равен «i», «s», «g», «p» и т. Д. c. Каждый тег соответствует другому типу сообщения. Например, тег 35 = 'i' соответствует QuoteMessage, а 35 = 'g' соответствует NewOrderMessage.

Я хотел бы иметь одну функцию с именем

public class MessageProcessor
{

private readonly IEnumerable<ICommand> _commands;

public List<IMessage> ProcessMessageByType(MessageType type);
    var command = _commands.Where(c => (char)type == c.Type).First();
    return command.Do(); // Returns a list of messages of this type.
}
public interface ICommand
{
   string RegexMatch { get; set; }
   bool IsMatch(string input);
   List<IMessage> Do();
}

public class ProcessTagICommand : ICommand
{
   public string RegexMatch = "i";
   bool IsMatch(string input) => Regex.Match(input, RegexMatch).Success;
   List<IMessage> Do()
   {
      return // a list of quoteMessages. This won't compile :'(
   }
}

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

public interface IMessage
{
    DateTime Timestamp { get; set; }
}

public class QuoteMessage : IMessage
{

}

public class OrderMessage : IMessage
{

}

Начиная с command.Do() выше, я бы возвратил List<QuoteMessage>, который по некоторым причинам не может быть преобразован в IMessage, даже если он реализует его интерфейс.

Может кто-нибудь объяснить мне лучший способ добиться того, чего я пытаюсь достичь?

1 Ответ

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

Самый простой ответ - использовать IEnumerable:

public interface ICommand
{

   IEnumerable<IMessage> Do();
}

public class ProcessTagICommand : ICommand
{

   public IEnumerable<IMessage> Do()
   {
      return new List<QuoteMessage>();
   }
}

Это потому, что IEnumerable позволяет установить ковариантный тип как IMessage, вы можете узнать больше о ковариации и контравариантности в do tnet: Ковариация и Контравариантность

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