在扩展上使用累加器

时间:2016-06-26 11:46:16

标签: c# .net range

我有以下Range类和扩展名:

public class Range<T> where T : IComparable<T> {
  public T Minimum { get; set; }
  public T Maximum { get; set; }

  public Range(T minimum, T maximum) {
    Minimum = minimum;
    Maximum = maximum; 
  } // Range
}

public static IEnumerable<T> Expand<T>(this Range<T> range, Func<T, T> accumulator) where T : IComparable<T> {

  T current = range.Minimum;

  while (current.CompareTo(range.Maximum) <= 0) {
    yield return current;
    current = accumulator(current);
  }

}

我正在尝试创建扩展范围的自定义方式。例如:

Range<Int32> range = new Range<Int32>(20, 24);
List<Int32> expect = new List<Int32> { 40, 21, 44, 23, 48 };
List<Int32> result = range.Expand(x => x % 2 == 0 ? x + 1 : x).ToList();
Assert.Equal(expect, result);

当我运行此代码时,我得到了异常:

Array dimensions exceeded supported range 

例如,如果我使用:

,也会发生同样的情况
List<Int32> result = range.Expand(x => 2 * x).ToList();

创建此扩展程序的正确方法是什么?

更新

我的工作如果使用:

List<Int32> result = range.Expand(x => ++x).ToList();

但是在使用时我得到了相同的异常:

List<Int32> result = range.Expand(x => x++).ToList();

为什么?

1 个答案:

答案 0 :(得分:0)

您的代码存在的问题是您没有获得您范围内的下一个项目。当你在累加器中有++x时,它会为你完成工作。您应该转到while循环中的下一个项目。由于您使用的是通用Range<T>,因此您必须定义如何获取下一个项目。

我认为最合适的名称是地图而不是累积器

public class Range<T>
{
    public T Minimum { get; set; }
    public T Maximum { get; set; }
    public Func<T, T> Next { get; set; }
    public Range(T min, T max) { Minimum = min; Maximum = max; }
}

public static IEnumerable<T> Expand<T>(this Range<T> range, Func<T, T> map) where T : IComparable<T>
{
    T current = range.Minimum;
    while (current.CompareTo(range.Maximum) <= 0)
    {
        var result = map(current);
        yield return result;
        current = range.Next(current);
    }
}


Range<Int32> range = new Range<Int32>(20, 24);
range.Next = x => x + 1;
List<Int32> expect = new List<Int32> { 40, 21, 44, 23, 48 };
List<Int32> result = range.Expand(x => x % 2 == 0 ? x * 2 : x).ToList();
Assert.Equal(expect, result);