würde ich etwas Ähnliches wie Jasons Lösung vorschlagen, sondern einen Wrapper verwenden, die IDataReader stattdessen implementiert, so:
sealed public class PeekDataReader : IDataReader
{
private IDataReader wrappedReader;
private bool wasPeeked;
private bool lastResult;
public PeekDataReader(IDataReader wrappedReader)
{
this.wrappedReader = wrappedReader;
}
public bool Peek()
{
// If the previous operation was a peek, do not move...
if (this.wasPeeked)
return this.lastResult;
// This is the first peek for the current position, so read and tag
bool result = Read();
this.wasPeeked = true;
return result;
}
public bool Read()
{
// If last operation was a peek, do not actually read
if (this.wasPeeked)
{
this.wasPeeked = false;
return this.lastResult;
}
// Remember the result for any subsequent peeks
this.lastResult = this.wrappedReader.Read();
return this.lastResult;
}
public bool NextResult()
{
this.wasPeeked = false;
return this.wrappedReader.NextResult();
}
// Add pass-through operations for all other IDataReader methods
// that simply call on 'this.wrappedReader'
}
Beachten Sie, dass dies ein ganz erfordert wenig Pass-Through-Code für alle nicht betroffenen Eigenschaften, Der Vorteil ist jedoch, dass es sich um eine generische Abstraktion handelt, die an jeder Position in der Ergebnismenge "spähen" kann, ohne bei der nachfolgenden "Lese" -Operation vorwärts zu gehen.
zu benutzen:
using (IDataReader reader = new PeekDataReader(/* actual reader */))
{
if (reader.Peek())
{
// perform some operations on the first row if it exists...
}
while (reader.Read())
{
// re-use the first row, and then read the remainder...
}
}
Beachten Sie aber, dass Anruf jeden ‚Peek()‘ wird tatsächlich auf den nächsten Datensatz verschieben, wenn die vorherige Operation nicht auch eine ‚Peek()‘ ist. Wenn Sie diese Symmetrie mit der Operation 'Read()' beibehalten, erhalten Sie eine einfachere Implementierung und eine elegantere API.
Ihr Beispiel funktioniert nicht, da die 'IDataReader' Schnittstelle selbst nicht Ihre' .Peek' Methode enthält. Sie sollten die benutzende Bereichsvariable explizit als 'PeekDataReader' eingeben oder' var' verwenden. – julealgon