In following struct, I'm using function to follow strategy pattern.
this is a simple range enumerator. if negative length is passed, it will enumerate reversely.
How ever it does not work as expected. when _move call is returned, Position remains unchanged. 
I guess I know the reason, its because struct is being copied somewhere. but I cant seem to find where copy is being made.
(using class instead of struct is not answer that I'm looking for.)
internal struct RangeEnumerator<T> : IEnumerator<T>
{
    private readonly Func<bool> _move;
    private readonly IReadOnlyList<T> _source;
    private readonly int _start;
    private readonly int _end;
    // position of enumerator. not actual index. negative if reversed
    public int Position { get; private set; }
    public RangeEnumerator(IReadOnlyList<T> source, int start, int length)
    {
        start = Math.Min(Math.Max(start, 0), source.Count);
        _source = source;
        _start = start;
        _end = Math.Min(Math.Max(length + start, 0), source.Count);
        Position = -Math.Sign(length);
        _move = null;
        _move = length >= 0 ? (Func<bool>) this.MoveNextImpl : this.MovePrevImpl;
    }
    public bool MoveNext() => _move();
    public void Reset() => Position = -1;
    public T Current => _source[Position + _start];
    object IEnumerator.Current => Current;
    private bool MoveNextImpl() => ++Position + _start < _end;
    private bool MovePrevImpl() => --Position + _start  >= _end;
    void IDisposable.Dispose()
    {
    }
}
Testing: for quick test, use the following code and debug.
public static class Program
{
    public static void Main(string[] args)
    {
        var list = new List<int> {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        var enumerator = new RangeEnumerator<int>(list, 3, 5); // 3 to 8 exclusive
        foreach (var x in enumerator.AsEnumerable(0))
        {
            Console.WriteLine(x);
        }
    }
}
internal static class EnumeratorExtensions
{
    public static StructEnumerable<TEnumerator, T> AsEnumerable<TEnumerator, T>(this TEnumerator enumerator, T _) where TEnumerator : struct, IEnumerator<T>
    {
        // struct copy doesn't matter since we didn't start enumerating yet.
        return new StructEnumerable<TEnumerator, T>(enumerator); 
    }
}
// Enumerable to be used by foreach.
internal struct StructEnumerable<TEnumerator, T> where TEnumerator : struct, IEnumerator<T>
{
    private TEnumerator _enumerator;
    public StructEnumerable(TEnumerator enumerator)
    {
        // struct copy doesn't matter since we didn't start enumerating yet.
        _enumerator = enumerator;
    }
    public TEnumerator GetEnumerator()
    {
        // struct copy doesn't matter since we didn't start enumerating yet.
        return _enumerator;
    }
}
