Para un enfoque funcional, que puede implementar un empadronador búsqueda hacia delante, así:
IEnumerable<Item> collection = ...;
var lookahead = collection.Zip(collection.Skip(1), Tuple.Create);
El empadronador se repetirá a través de tuplas de cada elemento y es punto siguiente. Esto excluye el último elemento de la colección. Entonces solo se trata de realizar la consulta.
var query = collection.Zip(collection.Skip(1), Tuple.Create)
.Where(tuple => tuple.Item1.Kind == null && tuple.Item2.Kind == null)
.Select(tuple => tuple.Item1);
Lamentablemente, esto será muy ineficiente. Está enumerando la longitud de la colección dos veces y puede ser muy costoso.
Sería mejor escribir su propio enumerador para este por lo que sólo va a través de la colección en una sola pasada:
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;
}
}
}
Entonces la pregunta se convierte en:
var query = collection.LookAhead(Tuple.Create)
.Where(tuple => tuple.Item1.Kind == null && tuple.Item2.Kind == null)
.Select(tuple => tuple.Item1);
veo un índice de excepción de rango en su solución: si el último elemento 'Tipo 'es' nulo', 'lista [i + 1]' sobreindexará la lista. – nemesv
Editado: Buena llamada. – Ocelot20
Todavía no es perfecto: reemplace 'i' con' i + 1' en 'ElementAtOrDefault' y' ElementAt' para hacerlo bien. – nemesv