Uso dei predicati in C#

di il
3 risposte

Uso dei predicati in C#

Come faccio a dichiarare un predicato che ammette due parametri? Ho una lista di oggetti e voglio utilizzare la funzione Find.

Predicate<Autoveicolo> predicato = TrovaTarga;

Autoveicolo auto_cercata = autos.Find(predicato);

private static bool TrovaTarga(Autoveicolo car, string targa) 
{
           if (car.Targa == targa ) return true;
           else return false;
}

3 Risposte

  • Re: Uso dei predicati in C#

    29/12/2022 - zoro82 ha scritto:


    Come faccio a dichiarare un predicato che ammette due parametri? Ho una lista di oggetti e voglio utilizzare la funzione Find.

    NON puoi cambiare il numero di parametri del metodo che passi alla funzione Find(), in quanto essa si aspetta di invocare un metodo il quale deve avere una firma precisa, e tale firma è quella definita dal tipo Predicate<>:

    • un parametro di ingresso che è l'elemento da esaminare di volta in volta, pescato dall'insieme degli elementi che viene enumerato;
    • un valore di ritorno booleano che indica se l'elemento corrisponde al filtro impostato.

    Il valore della targa che vuoi usare nel tuo filtro di esempio deve provenire dal contesto, che viene “catturato” automaticamente dal metodo anonimo.

    Ad esempio, supponendo che vi sia un metodo nel quale si acquisisce da una casella di testo il valore della targa e si voglia trovare la prima auto corrispondente, il codice sarà simile a quello che segue:

    var targaAuto = textBox1.Text;
    var autoTrovata = autos.Find(a => a.Targa == targaAuto);

    Nel tuo codice, non è chiaro perché gli elementi siano tutti disgiunti, ad ogni modo si potrebbe riscrivere così:

    Predicate<Autoveicolo> predicato = TrovaTarga;
    
    Autoveicolo auto_cercata = autos.Find(predicato);
    
    private static bool TrovaTarga(Autoveicolo car) 
    {
    	if (car.Targa == _targaAuto)
    		return true;
    	else
    		return false;
    }

    L'identificatore _targaAuto che ho usato nel codice sopra deve essere un campo, una variabile o qualsiasi cosa che possa essere visibile al metodo utilizzato come parametro della Find() al momento della ricerca.

    Ciao! :)

  • Re: Uso dei predicati in C#

    Ciao. Innanzitutto, grazie della risposta e poi perdona alcune mie inesattezze.

    Inizialmente, avevo optato anche io per la soluzione con l'espressione lambda. Tuttavia, cercavo una soluzione un po' più “schematica”  che facesse uso di un metodo non anonimo e al quale poter passare un parametro da utilizzare nel filtro. Credo non ci sia possibilità, a meno di utilizzare una variabile di classe privata come hai fatto tu (_targa).

    Avevo anche provato ad usare un delegato Func ma il metodo find non la digerisce bene.

  • Re: Uso dei predicati in C#

    30/12/2022 - zoro82 ha scritto:


    Inizialmente, avevo optato anche io per la soluzione con l'espressione lambda. Tuttavia, cercavo una soluzione un po' più “schematica”  che facesse uso di un metodo non anonimo e al quale poter passare un parametro da utilizzare nel filtro.

    Secondo me, più “schematico” e sintetico di una espressione lambda non c'è nulla. :)

    30/12/2022 - zoro82 ha scritto:


    Credo non ci sia possibilità, a meno di utilizzare una variabile di classe privata come hai fatto tu (_targa).

    Diciamo che quando il metodo viene eseguito, nello “scope” deve esserci qualcosa che contenga il valore da utilizzare nel filtro.

    Detto questo, che sia un campo privato o un'altra entità, la scelta è affidata allo sviluppatore.

    Fatico a capire qual è la struttura che stai cercando di creare e, di conseguenza, se può avere un senso a livello pratico, perché il problema che stai affrontando non è mai stato un ostacolo per me. :|

    30/12/2022 - zoro82 ha scritto:


    Avevo anche provato ad usare un delegato Func ma il metodo find non la digerisce bene.

    Certo che è così: C# è un linguaggio tipizzato, quindi ciò che passi deve essere compatibile con il tipo a cui appartiene il parametro da valorizzare, non si scappa.

    Func<> può essere usato se la definisci così

    Func<Autoveicolo, bool>

    ovvero se si riferisce a un metodo che accetta un parametro di tipo Autoveicolo e restituisce un valore di tipo Boolean: qualunque tentativo di usare tipi diversi, o più/meno parametri, non è ovviamente compatibile con la firma attesa per il metodo.

    Ciao! :)

Devi accedere o registrarti per scrivere nel forum
3 risposte