Extension method ricorsivo per LINQ

di Cristian Civera, in .NET 3.5,

Ultimamente sto giocando parecchio con LINQ e trovo incredibile come possa cambiare il modo di scrivere parti di codice: tutto diventa più leggibile e si ha subito l'idea di cosa una query faccia.

Oggi dovevo sfogliare tutte le sezioni di configurazioni e per ognuna chiamare il metodo ProtectSection per criptarla. Siccome ogni gruppo di configurazione ha delle sezioni e a sua volta dei sotto gruppi di configurazione, dovevo fare una funzione da richiamare in modo ricorsivo per ogni gruppo, ma non mi piaceva. La domanda che ormai mi pongo è: si può fare in LINQ? In questo caso no o almeno io non ho trovato un extension method o una combinazione di essi che facesse al caso mio. Perciò ne ho creato uno mio generico, per rendere flat una struttura ad albero:

public static class Extensions
{
  public static IEnumerable<t /> ToFlat<t />(this IEnumerable<t /> source, Func<T, IEnumerable<T><t, />> childPredicate)
  {
    foreach (T t in source)
    {
      yield return t;
      IEnumerable<t /> children = childPredicate(t);
      foreach (T child in ToFlat(children, childPredicate))
        yield return child;
    }
  }
}

In pratica, prende una lista e la sfoglia restituendo ogni elemento della lista stessa. Poi attraverso un predicato ottiene i figli di ogni elemento e per ognuno chiama ricorsivamente la funzione. In questo modo si ottiene un enumeratore piatto che sfoglia tutti gli elementi di una struttura ad al albero.

L'utilizzo poi è banale. Per esempio per sfogliare tutti i controlli di una pagina (il cast serve perché ControlsCollection non implementa IEnumerable):

var allControls = this.Controls.Cast<control />().ToFlat(c => c.Controls)

Semplice ed efficace, vero?

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Nella stessa categoria
I più letti del mese