it-swarm-id.com

Penggunaan C # Delegates di dunia nyata

Saya pikir saya secara konseptual memahami delegasi C #, namun, saya berjuang untuk menemukan contoh dunia nyata di mana mereka akan berguna. Dapatkah Anda memberikan beberapa jawaban yang merinci bagaimana delegasi C # digunakan dalam aplikasi nyata dan masalah apa yang memungkinkan Anda untuk melakukannya.

16
AlexC

Kode GUI menggunakan delegasi untuk menangani acara, seperti klik tombol, pemindahan jendela. Menggunakan delegasi memungkinkan Anda memiliki fungsi yang dipanggil setiap kali acara terjadi. Contohnya adalah menautkan fungsi yang menyimpan data ke tombol "Simpan" pada antarmuka. Ketika tombol diklik itu diatur untuk menjalankan fungsi yang menyimpan data. Ini berguna dalam pemrograman GUI karena seluruh program Anda bisa menunggu pengguna untuk melakukan sesuatu dan Anda tidak memiliki cara untuk mengetahui apa yang akan mereka lakukan terlebih dahulu. Menggunakan delegasi memungkinkan fungsionalitas program Anda untuk terhubung ke UI sedemikian rupa sehingga pengguna dapat melakukan hal-hal dengan cara apa pun yang mereka inginkan.

Linq menggunakan Func<T> dan Action<T> delegasi di semua tempat sebagai parameter.

Ini memungkinkan Anda untuk menggunakan ekspresi lambda sebagai parameter dan menentukan tindakan yang akan diambil sebagai bagian dari daftar parameter.

12
Oded

Hampir semua yang menggunakan Pola Pengamat kemungkinan akan menerapkan delegasi.

Baca deskripsi dan Anda mungkin akan membayangkan beberapa skenario di mana Anda akan menggunakannya. Penanganan acara GUI adalah contoh umum.

12
whatsisname

Delegasi sangat berguna dalam pemrograman asinkron.

Anda memiliki kelas yang melakukan hal-hal secara tidak sinkron dan memiliki panggilan balik. Anda dapat meminta metode delegasi dipanggil saat panggilan balik - dan implementasi kelas Anda akan melakukan logika yang dijelaskan dalam metode delegasi Anda.

9
James Love

Delegasi sangat berguna sebagai solusi untuk lubang di pola tengah . Pada dasarnya, ada banyak kasus di mana Anda ingin membungkus satu set instruksi unik di dalam sekelompok instruksi umum. Ini sangat sulit jika instruksi sebelum dan sesudah bit unik perlu berbagi status. Dengan delegasi, Anda bisa meneruskan delegasi ke suatu fungsi. Fungsi mengeksekusi bit sebelum, mengeksekusi delegasi, lalu mengeksekusi bit setelah.

9
Scott Whitlock

Di "masa lalu" bahasa non-OOP seperti Fortran dan C, itu sangat berguna untuk dapat memiliki subrutin menerima argumen yang merupakan penunjuk ke fungsi. Misalnya, fungsi qsort bekerja dengan fungsi perbandingan yang disediakan pengguna. Ada banyak subrutin untuk menyelesaikan persamaan diferensial biasa, atau untuk mengoptimalkan fungsi, dan mereka semua menggunakan pointer fungsi sebagai argumen.

Dalam sistem windowing, semua jenis callback mengikuti pola yang sama.

Di LISP, bahkan di masa-masa awal, ada sesuatu yang disebut "argumen fungsional" atau FUNARG, yang bukan hanya fungsi, tetapi juga mengandung konteks penyimpanan di mana ia dapat mengingat dan berinteraksi dengan bagian dari dunia luar.

Kebutuhan yang sama ada dalam bahasa OOP, kecuali ketika Anda melewati alamat fungsi Anda juga harus melewati alamat objek fungsi adalah metode. Itulah dua hal yang harus Anda lewati Jadi delegasi hanya itu, dan memungkinkan pola lama yang baik untuk tetap digunakan.

5
Mike Dunlavey

Berikut ini adalah contoh sederhana yang menunjukkan bagaimana delegasi yang berguna dapat membuat kode sederhana yang mengikuti prinsip DRY. Ini juga memungkinkan Anda untuk menjaga kode sangat dekat dengan tempat dibutuhkannya.

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

Ini adalah contoh nyata dari keuntungan yang diberikan oleh delegasi.

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

Pertemuan pertama saya dengan delegasi sedang memeriksa pembaruan program (windows form C # 3.5) dengan mengunduh file dari situs web saya, tetapi untuk menghindari pembaruan memeriksa mengunci seluruh program saya menggunakan delegasi dan utas untuk melakukannya secara sinkron.

2
Ken

Saya telah melihat implementasi yang menarik dari pola Strategi yang menggunakan delegasi secara efektif. (yaitu strategi adalah delegasi)

Yang saya cari adalah pathfinding di mana algoritma untuk menemukan path adalah delegasi yang dapat (kembali) ditugaskan pada saat runtime sehingga algoritma yang berbeda dapat digunakan (BFS vs A * dll.)

1
Steven Evers

Banyak pola GoF klasik dapat diimplementasikan dengan delegasi: Misalnya, pola Komando, pola Pengunjung, pola Strategi, pola Pabrik dan pola Pengamat sering dapat diimplementasikan dengan delegasi sederhana. Terkadang, kelas lebih baik (mis. Ketika perintah membutuhkan nama atau objek strategi perlu diserialisasi) tetapi dalam kebanyakan kasus, menggunakan Action<...> atau Func<...> jauh lebih elegan daripada membuat antarmuka satu metode khusus.

1
nikie