我试图找到一种更好的方法来处理一些不断增长的if
构造来处理不同类型的类。这些类最终是不同值类型(int、DateTime 等)的包装器,并带有一些额外的状态信息。因此,这些类之间的主要区别在于它们包含的数据类型。虽然它们实现了泛型接口,但它们还需要保存在同构集合中,因此它们还实现了非泛型接口。类实例根据它们所代表的数据类型进行处理,并且它们的传播继续或不继续基于此。
虽然这不一定是 .NET 或 C# 问题,但我的代码是用 C# 编写的。
示例类:
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;
}
有更好的选择吗?这两个选项中是否有我认为我不应该考虑的东西?