我正在努力寻找更好的方法来处理一些成长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;
}
有更好的选择吗?这两个选项中是否有一些我不认为应该做的事情?
方法 1,使用动态进行双重调度(归功于http://blogs.msdn.com/b/curth/archive/2008/11/15/c-dynamic-and-multiple-dispatch.aspx http://blogs.msdn.com/b/curth/archive/2008/11/15/c-dynamic-and-multiple-dispatch.aspx)。
基本上你可以像这样简化你的访客模式:
class Evaluator {
public void Evaluate(IEnumerable<ITimedValue> values) {
foreach(var v in values)
{
Eval((dynamic)(v));
}
}
private void Eval(DateTimeValue d) {
Console.WriteLine(d.Value.ToString() + " is a datetime");
}
private void Eval(NumericValue f) {
Console.WriteLine(f.Value.ToString() + " is a float");
}
}
使用示例:
var l = new List<ITimedValue>(){
new NumericValue(){Value= 5.1F},
new DateTimeValue() {Value= DateTime.Now}};
new Evaluator()
.Evaluate(l);
// output:
// 5,1 is a float
// 29/02/2012 19:15:16 is a datetime
方法 2 将使用 @Juliet 提议的 C# 中的 Union 类型here https://stackoverflow.com/questions/3151702/discriminated-union-in-c-sharp(替代实施here http://pastebin.com/EEdvVh2R)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)