this.resultSelector = resultSelector;
}
+ // If strict is set to `true', the zip'ing process will throw if sequences length mistmatches
+ public bool Strict {
+ get;
+ set;
+ }
+
internal override IEnumerable<TResult> GetSequential ()
{
IEnumerable<TFirst> first = Parent.GetSequential ();
return first
.Select ((f, i) => GetEnumerable (f, second[i]))
- .ToArray ();
+ .ToList ();
}
IEnumerable<TResult> GetEnumerable (IEnumerable<TFirst> first, IEnumerable<TSecond> second)
try {
while (eFirst.MoveNext ()) {
- if (!eSecond.MoveNext ())
- yield break;
+ if (!eSecond.MoveNext ()) {
+ if (Strict)
+ throw new QueryZipException ();
+ else
+ yield break;
+ }
yield return resultSelector (eFirst.Current, eSecond.Current);
}
+ if (Strict && eSecond.MoveNext ())
+ throw new QueryZipException ();
} finally {
eFirst.Dispose ();
eSecond.Dispose ();
return first
.Select ((f, i) => GetEnumerable (f, second[i], i , store1, store2, barrier))
- .ToArray ();
+ .ToList ();
}
IEnumerable<KeyValuePair<long, TResult>> GetEnumerable (IEnumerable<KeyValuePair<long, TFirst>> first,
try {
while (eFirst.MoveNext ()) {
- if (!eSecond.MoveNext ())
- break;
+ if (!eSecond.MoveNext ()) {
+ if (Strict)
+ throw new QueryZipException ();
+ else
+ break;
+ }
store1[index] = eFirst.Current;
store2[index] = eSecond.Current;
yield return new KeyValuePair<long, TResult> (store1[index].Key,
resultSelector (store1[index].Value, store2[index].Value));
}
+ if (Strict && eSecond.MoveNext ())
+ throw new QueryZipException ();
} finally {
barrier.RemoveParticipant ();
eFirst.Dispose ();
}
}
}
+
+ internal class QueryZipException : Exception
+ {
+ }
}
#endif