Collection e Delegate, come non incorporare le logiche di ricerca.

Ho un po' di tempo dovuto all'influenza (e un po' meno neuroni disponibili) ed ho deciso di scrivere un piccolo articolo visto che mi annoio a morte.

Mi è capitato tempo a dietro di dover implementare delle Collection personalizzate che dovevano poi essere utilizzate in vario modo.

Il problema che avevo davanti stava nei filtri. Avevo bisogno di eseguire diverse ricerche su queste collection... ma la logica con cui queste ricerche andavano effettuate non riguardava l'oggetto collection, ma l'oggetto utilizzatore.

Pensa che ti ripensa mi è venuta un'idea su come separare la logica per effettuare la ricerca da l'oggetto collection: i delegate.

L'idea è questa: Ho la classe alla base della collection:

public class MyData

{

public int Value;

public string Name;

public MyData(int value, string name)

{

Value = value;

Name = name;

}

}

Una classe molto semplice per semplificarci la vita.

Questo è il delegate della funzione di ricerca:

public delegate bool dFilterFunction (MyData Data);

 e la classe Collection:

class CustomList : List<MyData>

{

public CustomList Extract(dFilterFunction FilterFunction)

{

CustomList Result = new CustomList();

foreach (MyData Data in this)

{

if (FilterFunction(Data))

{

Result.Add(Data);

}

}

return Result;

}

}

Anche questa è molto semplice, grazie all'uso dei generics ho dovuto scrivere un solo metodo Extract.

Come funziona?  Ogni oggetto della collection viene inviato alla funzione di ricerca passaata come parametro. Questa funzione deve rispettare il delegate che abbiamo dichiarato ed un semplice Contratto. Dato un'oggetto la funzione deve restituire true, se l'oggetto è adatto false altrimenti. Infine il metodo restituisce una collection sottoinsieme della precedente con i soli oggetti che soddisfano i criteri di ricerca.

Infine un piccolo esempio d'uso:

class Program

{

/// <summary>

/// La funzione filtro

/// </summary>

public static bool FilterFunction(MyData Data)

{

return (Data.Value > 3);

}

static void Main(string[] args)

{

CustomList MyList = new CustomList();

MyList.Add(new MyData(1, "Uno"));

MyList.Add(new MyData(2, "Due"));

MyList.Add(new MyData(3, "Tre"));

MyList.Add(new MyData(4, "Quattro"));

MyList.Add(new MyData(5, "Cinque"));

MyList.Add(new MyData(6, "Sei"));

CustomList FList = MyList.Extract(Program.FilterFunction);

foreach (MyData Data in FList)

{

Console.WriteLine(Data.Name);

}

Console.ReadLine();

}

}

Per suggerimenti o informazioni non esistate a contattarmi.

posted @ mercoledì 7 marzo 2007 17:56

Print
«aprile»
domlunmarmergiovensab
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011