我怎样才能对范围扩展功能进行泛化?

时间:2015-02-25 17:24:21

标签: c#

我有以下课程:

public class State {
  public DateTime Created { get; set; }
  public Double A { get; set; }
  public Double B { get; set; }
}

然后我有两种状态:

State start = new State { Created = DateTime.UtcNow, A = 10.2, B = 20.5 }

State end = new State { Created = DateTime.UtcNow.AddDays(40), A = 1, B = 80 }

我想在开始和结束之间创建一个List,其中A和B的值在它们的起始值和结束值之间以线性方式发展。

我能够按如下方式创建一个List:

IList<DateTime> dates = new Range<DateTime>(start.Created, end.Created,).Expand(DateInterval.Day, 1)

Range和Expand是我创建的一些助手......

创造价值演变的最佳方法是什么?

我的想法会做类似的事情:

IList<State> states = new Range<State>( // here "tell" how each property would evolve ...)

更新

范围类

public class Range<T> where T : IComparable<T> {

    private T _minimum;
    private T _maximum;

    public T Minimum { get { return _minimum; } set { value = _minimum; } }
    public T Maximum { get { return _maximum; } set { value = _maximum; } }

    public Range(T minimum, T maximum) {
      _minimum = minimum;
      _maximum = maximum;
    } // Range

    public Boolean Contains(T value) {
      return (Minimum.CompareTo(value) <= 0) && (value.CompareTo(Maximum) <= 0);
    } // Contains

    public Boolean ContainsRange(Range<T> Range) {
      return this.IsValid() && Range.IsValid() && this.Contains(Range.Minimum) && this.Contains(Range.Maximum);
    } // ContainsRange

    public Boolean IsInsideRange(Range<T> Range) {
      return this.IsValid() && Range.IsValid() && Range.Contains(this.Minimum) && Range.Contains(this.Maximum);
    } // IsInsideRange

    public Boolean IsValid() {
      return Minimum.CompareTo(Maximum) <= 0;
    } // IsValid

    public override String ToString() {
      return String.Format("[{0} - {1}]", Minimum, Maximum);
    } // ToString

} // Range

一些范围扩展:

public static IEnumerable<Int32> Expand(this Range<Int32> range, Int32 step = 1) {
  Int32 current = range.Minimum;
  while (current <= range.Maximum) {
    yield return current;
    current += step;
  }
} // Expand

public static IEnumerable<DateTime> Expand(this Range<DateTime> range, TimeSpan span) {
  DateTime current = range.Minimum;
  while (current <= range.Maximum) {
    yield return current;
    current = current.Add(span);
  }
} // Expand

2 个答案:

答案 0 :(得分:1)

var magicNumber = 40;

var start = new State {Created = DateTime.UtcNow, A = 10.2, B = 20.5};
var end = new State {Created = DateTime.UtcNow.AddDays(magicNumber), A = 1, B = 80};

var stateList = new List<State>(magicNumber);

for (var i = 0; i < magicNumber; ++i)
{
    var newA = start.A + (end.A - start.A) / magicNumber * (i + 1);
    var newB = start.B + (end.B - start.B) / magicNumber * (i + 1);
    stateList.Add(new State { Created = DateTime.UtcNow.AddDays(i + 1), A = newA, B = newB });
}

答案 1 :(得分:0)

所以你已经进入了通用化的阶段,其中一个&#34;突变步骤&#34;将应用插值的可注入方法变得合乎逻辑。由于您没有足够的约束来知道如何插入步骤,因此您可能需要工厂方法来创建Func<T,T>实例。

例如,如果有两个属性的值在T中移动,则可以通过这种方式控制其变化率。

public class Point 
{
    int X {get;set;}
    int Y {get;set;}
}

public static IEnumerable<T> Expand(this Range<T> range, Func<T,T> stepFunction)
                               where T: IComparable<T>
{
     var current = range.Minimum;
     while (range.Contains(current))
     {
         yield return current;
         current = stepFunction(current);
     }
}

// in method
var pointRange = new Range<Point>(
                   new Point{ X=0,Y=0}, new Point{ X=5, Y=20});

foreach (Point p in pointRange.Expand(p => new Point{ p.X + 1, p.Y + 4})