it-swarm.asia

C # Delegelerinin gerçek dünya kullanımı

C # delegelerini kavramsal olarak anladığımı düşünüyorum, ancak faydalı olabilecekleri gerçek bir dünya örneği bulmak için mücadele ediyorum. C # delegelerinin gerçek uygulamalarda nasıl kullanıldığını ve etrafta dolaşmanızı sağlayan sorunları açıklayan bazı cevaplar verebilir misiniz?.

16
AlexC

GUI kodu, düğme tıklamaları, pencere hareketleri gibi olayları işlemek için temsilciler kullanır. Temsilciyi kullanmak, olay gerçekleştiğinde çağrılan bir işleve sahip olmanızı sağlar. Bir örnek, verileri kaydeden bir işlevi arabirimdeki "Kaydet" düğmesine bağlamak olabilir. Düğme tıklandığında veri kaydeden işlevi yürütecek şekilde ayarlanır. GUI programlamada kullanışlıdır, çünkü tüm programınız kullanıcının bir şeyler yapmasını bekliyor olabilir ve ilk önce ne yapacaklarını bilmenin bir yolu yoktur. Temsilci kullanmak, programınızın işlevselliğinin kullanıcı arabirimine, kullanıcının işleri istediği şekilde yapabileceği şekilde bağlanmasına olanak tanır.

Linq Func<T> ve Action<T> her yerde parametre olarak yetki verir.

Bunlar lambda ifadelerini parametre olarak kullanmanızı ve parametre listesinin bir parçası olarak gerçekleştirilecek eylemi tanımlamanızı sağlar.

12
Oded

Hemen hemen Gözlemci Düzeni kullanan her şey delegeleri uygular.

Açıklamayı okuyun ve muhtemelen bunları kullanacağınız bazı senaryolar hayal edeceksiniz. GUI olay işleme yaygın bir örnektir.

12
whatsisname

Delegeler, asenkron programlamada kanlı yararlıdır.

Eşzamansız olarak iş yapan ve geri arama yapan bir sınıfınız var. Temsilci yöntemini geri çağırma üzerine çağırabilirsiniz - ve sınıf uygulamanız temsilci yönteminizde açıklanan mantığı yapar.

9
James Love

Delegeler özellikle orta kalıptaki delik için bir çözüm olarak kullanışlıdır. Esasen, bir dizi talimatın içine benzersiz bir talimat kümesi sarmak istediğiniz birçok durum vardır. Benzersiz bitin öncesi ve sonrası talimatların durumu paylaşması gerekiyorsa özellikle zordur. Delegelerle, bir temsilciyi bir işleve geçirebilirsiniz. İşlev önce biti yürütür, temsilci yürütür, sonra sonraki biti yürütür.

9
Scott Whitlock

Fortran ve C gibi OOP olmayan dillerin "eski günlerinde", bir altyordamın bir işleve işaret eden bir argüman almasını sağlamak son derece yararlı oldu. Örneğin, qsort işlevi, kullanıcı tarafından sağlanan bir karşılaştırma işleviyle çalışır. Sıradan diferansiyel denklemleri çözmek veya fonksiyonları optimize etmek için çok sayıda alt rutin vardır ve hepsi fonksiyon işaretlerini argüman olarak alır.

Pencereleme sistemlerinde, her türlü geri arama aynı modeli izler.

LISP'de, ilk günlerde bile, "işlevsel bir argüman" veya FUNARG adı verilen bir şey vardı, bu sadece bir işlev değildi, aynı zamanda dış dünyanın bir kısmını hatırlayabileceği ve etkileşime girebileceği bir depolama bağlamı içeriyordu.

Aynı gereksinim OOP dillerinde de mevcuttur, ancak bir işlevin adresini geçtiğinizde, işlevin bir yöntem olduğu nesnenin adresini de iletmeniz gerekir. Bu, iletmeniz gereken iki şeydir) Delege sadece budur ve eski güzel modelin hala kullanılmasına izin verir.

5
Mike Dunlavey

Aşağıda, DRY ilkesini izleyen basit bir kod oluştururken temsilcilerin ne kadar yararlı olabileceğini gösteren basit bir örnek bulunmaktadır.

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

İşte delegelerin sağladığı avantajın gerçek dünya örneği.

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

Delegelerle ilk karşılaşmam, web sitemden bir dosya indirerek bir program güncellemesi (Windows C # 3.5 formları) kontrol ediyordu, ancak güncellemenin tüm programı kilitlemesini kontrol etmekten kaçınmak için senkronize olmayan bir şekilde bir temsilci ve bir iş parçacığı kullandım.

2
Ken

Delegeleri etkili bir şekilde kullanan Strateji modelinin ilginç uygulamalarını gördüm. (yani strateji bir temsilcidir)

Baktığım yol, yolu bulmak için algoritmanın çalışma zamanında (yeniden) atanabilecek bir temsilci olduğu yol bulma içindi, böylece farklı algoritmalar kullanılabilirdi (BFS vs A * vb.)

1
Steven Evers

Klasik GoF kalıplarının çoğu delegelerle uygulanabilir: Örneğin, Komut kalıbı, Ziyaretçi kalıbı, Strateji kalıbı, Fabrika kalıbı ve Gözlemci kalıbı genellikle basit bir delege ile uygulanabilir. Bazen bir sınıf daha iyidir (örneğin bir komutun bir ad veya bir strateji nesnesinin serileştirilmesi gerektiğinde), ancak çoğu durumda Action<...> veya Func<...>, özel bir tek yöntemli arayüz oluşturmaktan çok daha zariftir.

1
nikie