Uso del mondo reale dei delegati C # [chiuso]

14

Penso di capire a livello concettuale i delegati di C #, tuttavia, sto lottando per trovare un esempio di mondo reale in cui sarebbero utili. Puoi fornire alcune risposte in dettaglio su come i delegati C # sono stati utilizzati nelle applicazioni reali e quali problemi hanno permesso di aggirare.

    
posta AlexC 28.02.2011 - 21:54
fonte

10 risposte

15

Il codice GUI utilizza i delegati per gestire gli eventi, come i clic sui pulsanti, i movimenti delle finestre. L'utilizzo del delegato consente di avere una funzione chiamata ogni volta che si verifica l'evento. Un esempio potrebbe essere il collegamento di una funzione che salva i dati in un pulsante "Salva" sull'interfaccia. Quando si fa clic sul pulsante, viene impostato per eseguire la funzione che salva i dati. È utile nella programmazione della GUI perché il tuo intero programma potrebbe essere in attesa che l'utente faccia qualcosa e non hai modo di sapere cosa faranno prima. L'utilizzo dei delegati consente di collegare la funzionalità del tuo programma all'interfaccia utente in modo tale che l'utente possa fare le cose nel modo che preferisce.

    
risposta data 28.02.2011 - 21:58
fonte
12

Praticamente qualsiasi cosa utilizzi il modello di osservatore probabilmente implementerà i delegati.

Leggi la descrizione e probabilmente immaginerai alcuni scenari in cui li useresti. La gestione degli eventi della GUI è un esempio comune.

    
risposta data 28.02.2011 - 22:05
fonte
11

Linq usa Func<T> e Action<T> delega in tutto il luogo come parametri.

Questi ti permettono di usare espressioni lambda come parametri e definire l'azione da prendere come parte dell'elenco dei parametri.

    
risposta data 28.02.2011 - 22:04
fonte
9

I delegati sono dannatamente utili nella programmazione asincrona.

Hai una classe che fa roba in modo asincrono e ha un callback. È possibile invocare il metodo delegate durante la richiamata e l'implementazione della classe eseguirà la logica descritta nel metodo delegato.

    
risposta data 28.02.2011 - 22:11
fonte
9

I delegati sono particolarmente utili come soluzione per buco nel motivo centrale . In sostanza, ci sono molti casi in cui si desidera racchiudere un insieme unico di istruzioni all'interno di un gruppo comune di istruzioni. È particolarmente difficile se le istruzioni prima e dopo il bit univoco devono condividere lo stato. Con i delegati, puoi semplicemente passare un delegato in una funzione. La funzione esegue il bit precedente, esegue il delegato, quindi esegue il after bit.

    
risposta data 28.02.2011 - 22:30
fonte
5

Nei "vecchi tempi" di linguaggi non OOP come Fortran e C, era incredibilmente utile poter avere una subroutine per ricevere un argomento che era un puntatore a una funzione. Ad esempio, la funzione qsort funziona con una funzione di confronto fornita dall'utente. Esistono numerose subroutine per risolvere equazioni differenziali ordinarie o per ottimizzare le funzioni, e tutte considerano i puntatori di funzione come argomenti.

Nei sistemi di finestre, tutti i tipi di callback seguono lo stesso schema.

In Lisp, anche nei primi tempi, c'era qualcosa chiamato "argomento funzionale" o FUNARG, che non era solo una funzione, ma conteneva anche un contesto di archiviazione in cui poteva ricordare e interagire con parte del mondo esterno .

Questo stesso bisogno esiste nei linguaggi OOP, tranne quando si passa l'indirizzo di una funzione è necessario passare anche l'indirizzo dell'oggetto la cui funzione è un metodo di. Queste sono due cose che devi passare. Quindi un delegato è proprio questo e consente di utilizzare quel buon vecchio modello.

    
risposta data 28.02.2011 - 22:48
fonte
3

Ecco un semplice esempio che mostra quanto siano utili i delegati nella creazione di codice semplice che segue il principio DRY. Consente inoltre di mantenere il codice estremamente vicino a dove è necessario.

Action<Button, Action<Button>> prepareButton = 
    (btn, nxt) => { 
        btn.Height = 32;
        btn.Width= 64;
        nxt(btn);
    };

prepareButton(myBtn1, btn => btn.Text = "A");
prepareButton(myBtn2, btn => btn.Text = "B");
prepareButton(myBtn3, btn => btn.Text = "C");

Ecco un esempio reale del vantaggio offerto dai delegati.

protected override void PageInitialize()
{
    const string selectCodeFormat = "javascript:selectCode('{0}', '{1}');";
    const string onClick = "return toggleElement(this);";

    Func<HtmlGenericControl> getElement = null;
    Action<HtmlGenericControl> setElement = null, addChild = null;
    HtmlGenericControl level1Element = null, level2Element = null, level3Element = null, level4Element = null;
    string className = null, code = null, description = null;           

    using (var records = Core.Database.ExecuteRecords("code.SocCodeTree"))
    {
        while (records.Read())
        {
            code = records.GetString("Code");
            description = records.GetString("Description"); 

            if (records.GetString("Level4") != "")
            {
                className = "Level4";
                setElement = e => level4Element = e;
                getElement = () => level4Element;
                addChild = e => level3Element.Controls.Add(e);
            }
            else if (records.GetString("Level3") != "")
            {
                className = "Level3";
                setElement = e => level3Element = e;
                getElement = () => level3Element;
                addChild = e => level2Element.Controls.Add(e);
            }
            else if (records.GetString("Level2") != "")
            {
                className = "Level2";
                setElement = e => level2Element = e;
                getElement = () => level2Element;
                addChild = e => level1Element.Controls.Add(e);
            }
            else
            {
                className = "Level1";
                setElement = e => level1Element = e;
                getElement = () => level1Element;
                addChild = e => Root.Controls.Add(e);
            }

            var child = new HtmlGenericControl("li");
            child.Attributes["class"] = className;
            var span = new HtmlGenericControl("span") { 
                InnerText = code + " - " + description + " - " 
            };
            span.Attributes["onclick"] = onClick;
            child.Controls.Add(span);
            var a = new HtmlAnchor() { 
                InnerText = "Select", 
                HRef = string.Format(selectCodeFormat, code, description) 
            };
            child.Controls.Add(a);
            setElement(new HtmlGenericControl("ul"));
            child.Controls.Add(getElement());
            addChild(child);    
        }
    }
}
    
risposta data 28.02.2011 - 22:14
fonte
2

Il mio primo incontro con i delegati stava verificando un aggiornamento del programma (Windows Form C # 3.5) scaricando un file dal mio sito Web, ma per evitare il controllo degli aggiornamenti bloccando l'intero programma ho usato un delegato e un thread per farlo in modo asincrono.

    
risposta data 01.03.2011 - 00:37
fonte
1

Ho visto implementazioni interessanti del modello di strategia che utilizza i delegati in modo efficace. (cioè la strategia è un delegato)

Quello che stavo osservando era per il pathfinding in cui l'algoritmo per trovare il percorso era un delegato che poteva essere (ri) assegnato a runtime in modo che potessero essere usati algoritmi diversi (BFS vs A * ecc.)

    
risposta data 28.02.2011 - 22:09
fonte
1

Molti dei classici pattern GoF possono essere implementati con i delegati: ad esempio, Command pattern, Visitor pattern, Pattern di strategia, Pattern di fabbrica e pattern di Observer possono spesso essere implementati con un semplice delegato. A volte, una classe è migliore (ad esempio quando un comando ha bisogno di un nome o di un oggetto strategia deve essere serializzato) ma nella maggior parte dei casi, usando Action<...> o Func<...> è molto più elegante di creare un'interfaccia a un metodo dedicata.

    
risposta data 28.02.2011 - 23:49
fonte

Leggi altre domande sui tag