Я пытаюсь найти лучший способ обработать некоторые растущие конструкции if
для обработки классов разных типов. Эти классы, в конечном счете, обертывают вокруг разрозненных типов значений (int, DateTime и т.д.) С некоторой дополнительной информацией о состоянии. Таким образом, основное различие между этими классами - это тип данных, которые они содержат. Хотя они реализуют общие интерфейсы, их также нужно хранить в однородных коллекциях, поэтому они также реализуют не общий интерфейс. Экземпляры класса обрабатываются в соответствии с типом данных, которые они представляют, и их пропозиция продолжается или не продолжается на основе этого.
Хотя это не обязательно проблема .NET или С#, мой код находится на С#.
Примеры классов:
interface ITimedValue {
TimeSpan TimeStamp { get; }
}
interface ITimedValue<T> : ITimedValue {
T Value { get; }
}
class NumericValue : ITimedValue<float> {
public TimeSpan TimeStamp { get; private set; }
public float Value { get; private set; }
}
class DateTimeValue : ITimedValue<DateTime> {
public TimeSpan TimeStamp { get; private set; }
public DateTime Value { get; private set; }
}
class NumericEvaluator {
public void Evaluate(IEnumerable<ITimedValue> values) ...
}
У меня есть два варианта:
Двойная отправка
Недавно я узнал о шаблоне посетителя и его использовании двойной отправки для обработки именно такого случая. Это требует, потому что это позволит нежелательным данным не распространяться (если мы хотим обрабатывать int, мы можем обрабатывать это иначе, чем DateTime). Кроме того, поведение того, как обрабатываются различные типы, ограничивается одним классом, который обрабатывает отправку. Но есть справедливое обслуживание, если/когда необходимо поддерживать новый тип значения.
Класс объединения
Класс, содержащий свойство для каждого поддерживаемого типа значений, может быть тем, что хранится в каждом из этих классов. Любая операция над значением повлияет на соответствующий компонент. Это менее сложное и меньшее обслуживание, чем стратегия двойного диспетчеризации, но это будет означать, что каждая часть данных будет распространяться без всякой необходимости, поскольку вы больше не можете различать строки "Я не работаю над этим типом данных". Однако, если/когда новые типы должны поддерживаться, им нужно только перейти в этот класс (плюс любые дополнительные классы, которые необходимо создать для поддержки нового типа данных).
class UnionData {
public int NumericValue;
public DateTime DateTimeValue;
}
Есть ли лучшие варианты? Есть ли что-то в любом из этих двух вариантов, которые я не считал, что должен?