it-swarm-eu.dev

Využití delegátů C # v reálném světě

Myslím, že konceptuálně rozumím delegátům C #, snažím se však najít příklad skutečného světa, kde by byli užiteční. Můžete poskytnout několik odpovědí s podrobnostmi o tom, jak byli delegáti C # použity ve skutečných aplikacích a jaké problémy vám umožnily obejít.

16
AlexC

Kód GUI používá delegáty pro zpracování událostí, jako jsou kliknutí na tlačítka, pohyby okna. Použití delegáta vám umožňuje zavolat funkci vždy, když dojde k události. Příkladem by bylo propojení funkce, která ukládá data, s tlačítkem „Uložit“ na rozhraní. Po kliknutí na tlačítko je nastaveno na provedení funkce, která ukládá data. Je to užitečné v programování grafického uživatelského rozhraní, protože celý váš program by mohl čekat, až uživatel něco udělá, a vy nemůžete vědět, co udělá jako první. Použití delegátů umožňuje připojit funkčnost vašeho programu k uživatelskému rozhraní tak, aby uživatel mohl dělat věci libovolným způsobem.

Linq používá Func<T> a Action<T> deleguje všude místo jako parametry.

Umožňují vám použít výrazy lambda jako parametry a definovat akci, která má být provedena jako součást seznamu parametrů.

12
Oded

Prakticky cokoli používající Observer Pattern by pravděpodobně implementovalo delegáty.

Přečtěte si popis a pravděpodobně si představíte některé scénáře, kde byste je použili. Běžným příkladem je zpracování událostí GUI.

12
whatsisname

Delegáti jsou krvavé užitečné v asynchronním programování.

Máte třídu, která dělá věci asynchronně a má zpětné volání. Metodu delegate můžete nechat vyvolat při zpětném volání - a implementace vaší třídy provede logiku popsanou v metodě delegate.

9
James Love

Delegáti jsou zvláště užiteční jako řešení pro díra ve středním vzor . V podstatě existuje spousta případů, kdy chcete zabalit jedinečnou sadu instrukcí do společné svazky instrukcí. Je to obzvláště obtížné, pokud pokyny před a po jedinečném bitu potřebují sdílet stav. U delegátů můžete delegáta jen předat do funkce. Funkce provede bit před, provede delegáta a poté provede bit po.

9
Scott Whitlock

Ve „starých dobách“ non-OOP jazyků, jako je Fortran a C, bylo neuvěřitelně užitečné mít možnost, aby podprogram obdržel argument, který byl ukazatelem funkce. Například funkce qsort funguje s porovnávací funkcí poskytovanou uživatelem. Existuje řada podprogramů pro řešení obyčejných diferenciálních rovnic nebo pro optimalizaci funkcí a všechny berou ukazatele funkcí jako argumenty.

U okenních systémů se všechny typy zpětných volání řídí stejným vzorem.

V LISP, dokonce v počátcích, bylo něco, co se nazývalo „funkční argument“ nebo FUNARG, což nebylo jen funkcí, ale obsahovalo také kontext úložiště, kde si pamatovalo a interagovalo s částí vnějšího světa.

Stejná potřeba existuje v OOP jazycích), s výjimkou případů, kdy předáte adresu funkce, musíte také předat adresu objektu, jehož funkce je metoda. To jsou dvě věci, které musíte předat Delegát je jen to, a umožňuje, aby se tento dobrý starý vzor stále používal.

5
Mike Dunlavey

Zde je jednoduchý příklad, který ukazuje, jak užiteční delegáti mohou být při vytváření jednoduchého kódu, který dodržuje zásadu DRY princip. Rovněž umožňuje udržovat kód velmi blízko tam, kde je to potřeba).

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");

Zde je příklad výhod, které delegáti poskytují.

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);    
        }
    }
}
3
ChaosPandion

Moje první setkání s delegáty bylo kontrola aktualizace programu (formuláře Windows C # 3.5) stažením souboru z mého webu, ale abych se vyhnul kontrole kontroly zamykání celého programu, použil jsem delegáta a vlákno, abych to asynchronně provedl.

2
Ken

Viděl jsem zajímavé implementace vzoru Strategie, které efektivně využívá delegáty. (tj. strategie je delegátem)

Jediný, na který jsem se díval, bylo hledat cestu, kde algoritmus pro nalezení cesty byl delegát, kterého by bylo možné (znovu) přiřadit za běhu, aby bylo možné použít různé algoritmy (BFS vs A * atd.)

1
Steven Evers

Mnoho klasických vzorů GoF lze implementovat s delegáty: Například příkazový vzor, ​​vzor návštěvníka, strategický vzor, ​​tovární vzor a vzor pozorovatele lze často implementovat pomocí jednoduchého delegáta. Někdy je třída lepší (např. Když příkaz potřebuje jméno nebo je třeba serializovat objekt strategie), ale ve většině případů pomocí Action<...> nebo Func<...> je mnohem elegantnější než vytvoření jednoúčelového rozhraní.

1
nikie