2011-04-29 14 views
6

he implementado un ExtensionMethod que básicamente funciona como ParaCada-Loop, mi implementación es el siguiente:Método de extensión ParaCada para ListItemCollection

public static void ForEach(this ListItemCollection collection, Action<ListItem> act) 
{ 
    foreach (ListItem item in collection) 
     act(item); 
} 

Sin embargo, me gustaría que el método para detener un bucle después de la primera vez que una específica la condición se cumple.

Así es como actualmente lo uso:

ddlProcesses.Items.ForEach(item => item.Selected = item.Value == Request["Process"]?true:false); 

El problema con esto es que sólo puede haber un elemento dentro de la DropDownList que coincide con este requisito, pero el bucle se está terminando de todos modos, lo que sería el menos fea manera de resolver este problema?

Gracias.

+2

¿Por qué no usa ** Buscar **? – V4Vendetta

+3

Si no está experimentando ** ddlProcesses.Items.FindByValue (Request ["Process"]). Selected = true; ** sería la cosa más simple de hacer – V4Vendetta

+0

@ V4Vendetta: Use tilde para resaltar 'sintaxis en los comentarios' – abatishchev

Respuesta

5

Usted puede tomar un Func<ListItem, bool> en lugar de un Action<ListItem> y romper el bucle si devuelve true:

public static void ForEach(this ListItemCollection collection, 
    Func<ListItem, bool> func) 
{ 
    foreach (ListItem item in collection) { 
     if (func(item)) { 
      break; 
     } 
    } 
} 

Se puede utilizar la siguiente manera:

ddlProcesses.Items.ForEach(
    item => item.Selected = (item.Value == Request["Process"])); 
1

En primer lugar hacer esto:

IEnumerable<ListItem> e = ddlProcesses.Items.OfType<ListItem>(); // or Cast<ListItem>() 

para obtener una colección genérica.

Entonces use can roll your own, generic extension method:

public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action) 
{ 
    foreach (T item in collection) action(item); 
} 

public static void ForEach<T>(this IEnumerable<T> collection, Func<T> func) 
{ 
    foreach (T item in collection) if (func(item)) return; 
} 

De todos modos, caché de resultados de búsqueda:

var process = Request["Process"]; 

e.ForEach(i => i.Selected = i.Value == process); 
+0

e.ToList() resulta en copiar toda la lista en una nueva instancia de lista antes de iterar. Esto puede no ser deseable. –

2
public static void ForEach(this ListItemCollection collection, Action<ListItem> act) 
{ 
    foreach (ListItem item in collection) 
    { 
     act(item); 
     if(condition) break; 
    } 
} 
+0

¿De dónde viene la condición? –

+0

@abatischev esto es de OP "Me gustaría que el método deje de curvar después de la primera vez que se cumple una condición específica". – Gabriel

+0

@Peter the OP podría poner su condición allí ... Solo quería hacerle saber que puede detener un ciclo foreach con un descanso; – Gabriel

1

Sus necesidades no son 100% claro. ¿Necesita procesar todos los elementos para establecerlos en falso excepto el único que coincida con la condición o simplemente desea encontrar el que tenga la condición correcta o desea aplicar una función hasta que se cumpla una condición?

  1. Sólo hacer algo para un artículo por primera vez la condición coincide

    public static void ApplyFirst(this ListItemCollection collection, 
             Action<ListItem> action, Func<ListItem, bool> predicate) 
    { 
        foreach (ListItem item in collection) 
        { 
         if (predicate(item)) 
         { 
          action(item); 
          return; 
         } 
        } 
    } 
    
  2. Hacer algo a un elemento cada vez que una condición coincide

    public static void ApplyIf(this ListItemCollection collection, 
             Action<ListItem> action, Func<ListItem, bool> predicate) 
    { 
        foreach (ListItem item in collection) 
        { 
         if (predicate(item)) 
         { 
          action(item); 
         } 
        } 
    } 
    
  3. hacer algo para todos los elementos hasta una condición coincide con

    public static void ApplyUntil(this ListItemCollection collection, 
             Action<ListItem> action, Func<ListItem, bool> predicate) 
    { 
        foreach (ListItem item in collection) 
        { 
         action(item); 
         if (predicate(item)) 
         { 
          return; 
         } 
        } 
    } 
    
Cuestiones relacionadas