You could create a state machine that tracks peek-mode vs regular-mode. Maybe something like this (could just toss them all into a single file called Peeker.cs or something like that):
public sealed class Peeker
{
internal readonly PeekMode PEEKING;
internal readonly NormalMode NORMAL;
private ReadState _state;
public Peeker()
{
PEEKING = new PeekMode(this);
NORMAL = new NormalMode(this);
// Start with a normal mode
_state = NORMAL;
}
public object[] OnRead(IDataReader dr, bool peek)
{
return _state.OnRead(dr, peek);
}
internal void SetState(ReadState state)
{
_state = state;
}
}
internal abstract class ReadState
{
protected Peeker _peeker;
protected ReadState(Peeker p)
{
_peeker = p;
}
public abstract object[] OnRead(IDataReader dr, bool peek);
}
internal class PeekMode : ReadState
{
public PeekMode(Peeker p)
: base(p)
{
}
public override object[] OnRead(IDataReader dr, bool peek)
{
object[] datarow = new object[dr.FieldCount];
if (peek)
{
dr.GetValues(datarow);
}
else
{
if (dr.Read())
{
dr.GetValues(datarow);
_peeker.SetState(_peeker.NORMAL);
}
}
return datarow;
}
}
internal class NormalMode : ReadState
{
public NormalMode(Peeker p)
: base(p)
{
}
public override object[] OnRead(IDataReader dr, bool peek)
{
object[] datarow = new object[dr.FieldCount];
if (peek)
{
if (dr.Read())
{
dr.GetValues(datarow);
_peeker.SetState(_peeker.PEEKING);
}
}
else
{
if (dr.Read())
{
dr.GetValues(datarow);
}
}
return datarow;
}
}
Kind of overkill, but oh well.
To use it you would just do the following:
Peeker p = new Peeker();
.
.
.
SomeDataReaderType dr = SomeCommandType.ExecuteReader();
.
.
.
// To peek
object[] myDataRow = p.OnRead(dr, true);
// or not to peek
object[] myDataRow = p.OnRead(dr, false);
Then do what you need to do with your row. There might be a better way than using an object array, but you get the point.
Good luck!