Für einen funktionalen Ansatz, Sie kann wie so einen Look-Ahead-Enumerator implementieren:
IEnumerable<Item> collection = ...;
var lookahead = collection.Zip(collection.Skip(1), Tuple.Create);
der enumerator wird durch Tupel der einzelnen Elemente durchlaufen und es folgende Artikel. Dies schließt das letzte Element in der Sammlung aus. Dann ist es nur eine Frage der Abfrage.
var query = collection.Zip(collection.Skip(1), Tuple.Create)
.Where(tuple => tuple.Item1.Kind == null && tuple.Item2.Kind == null)
.Select(tuple => tuple.Item1);
Leider wird dies sehr ineffizient sein. Sie zählen die Länge der Sammlung zweimal auf und können sehr teuer sein.
Es wäre besser, Ihre eigenen Enumerator für diese zu schreiben, so dass Sie nur in einem Durchgang die Sammlung durchlaufen:
public static IEnumerable<TResult> LookAhead<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, TSource, TResult> selector)
{
if (source == null) throw new ArugmentNullException("source");
if (selector == null) throw new ArugmentNullException("selector");
using (var enumerator = source.GetEnumerator())
{
if (!enumerator.MoveNext())
{
//empty
yield break;
}
var current = enumerator.Current;
while (enumerator.MoveNext())
{
var next = enumerator.Current;
yield return selector(current, next);
current = next;
}
}
}
Dann wird die Abfrage wird:
var query = collection.LookAhead(Tuple.Create)
.Where(tuple => tuple.Item1.Kind == null && tuple.Item2.Kind == null)
.Select(tuple => tuple.Item1);
Ich sehe einen Index aus Range Exception in Ihrer Lösung: Wenn das letzte Element 'Kind'' null' ist, dann wird 'list [i + 1]' die Liste überindizieren. – nemesv
Bearbeitet: Guter Anruf. – Ocelot20
Immer noch nicht perfekt: Ersetzen Sie "i" durch "i + 1" in "ElementAtOrDefault" und "ElementAt", um es richtig zu machen. – nemesv