Temsilcileri nerede kullanırım? [kapalı]


109

Delegeleri çağıran gerçek dünyadaki yerler nelerdir? Bu yöntemin en iyi çözüm olduğu durumlarda hangi durumların veya modellerin mevcut olduğunu merak ediyorum. Kod gerekmez.

Yanıtlar:


33

Temsilci, belirli bir yöntem türünü tanımlayan adlandırılmış bir türdür. Bir sınıf tanımının, tanımladığı belirli nesne türü için tüm üyeleri düzenlediği gibi, temsilci de tanımladığı yöntem türü için yöntem imzasını düzenler.

Bu ifadeye dayanarak, bir delege bir işlev göstericisidir ve bu işlevin neye benzediğini tanımlar.

Bir temsilcinin gerçek dünyadaki uygulaması için harika bir örnek Predicate'dir . Bağlantıdaki örnekte, Array.Find'ın diziyi aramaya ve ardından ne bulunacağına ilişkin ölçütleri işlemek için bir yüklem aldığını fark edeceksiniz . Bu durumda, Predicate imzasıyla eşleşen bir ProductGT10 yönteminden geçer.


154

"C # 3.0'ı Öğrenmek: C # 3.0'ın temellerinde ustalaşın" bölümünde belirtildiği gibi

Genel Senaryo: Bir devlet başkanı öldüğünde, Birleşik Devletler Başkanı'nın genellikle cenazeye şahsen katılmak için vakti yoktur. Bunun yerine bir temsilci gönderir. Genellikle bu delege Başkan Yardımcısıdır, ancak bazen Başkan Yardımcısı mevcut değildir ve Başkan, Dışişleri Bakanı ve hatta First Lady gibi başka birini göndermek zorundadır. Yetkisini tek bir kişiye "bağlamak" istemiyor; bu sorumluluğu doğru uluslararası protokolü uygulayabilen herkese devredebilir.

Başkan, hangi sorumluluğun devredileceğini (cenazeye katılacağını), hangi parametrelerin geçeceğini (taziyeler, nazik sözler) ve geri kazanmayı umduğu değeri (iyi niyet) önceden belirler. Daha sonra, başkanlığı ilerledikçe "çalışma zamanında" belirli bir kişiyi bu devredilen sorumluluğa atar.

Senaryo programlamada: Genellikle belirli bir eylemi yürütmeniz gereken durumlarla karşılaşırsınız, ancak önceden hangi yöntemi, hatta hangi nesneyi yürütmek için çağırmak isteyeceğinizi önceden bilmiyorsunuz.

Örneğin: Bir düğme, hangi nesneye veya nesnelere bildirimde bulunulması gerektiğini bilmeyebilir. Düğmeyi belirli bir nesneye bağlamak yerine, düğmeyi bir temsilciye bağlayacak ve ardından program çalıştırıldığında bu temsilciyi belirli bir yönteme çözeceksiniz.


1
Öyleyse neden anonim işlevleri / lambdaları kullanmıyorsunuz?
Pacerier

5
@Pacerier Bu geç bir yanıttır ve yanıtı keşfetmiş olabilirsiniz, ancak bunu bulan diğer okuyucular için: anonim bir işlev bir tür delege türüdür.
Anthony

10
@ Anthony + Pacerier: Uyumsuz bir yöntem delege DEĞİLDİR. Anonim bir yöntem, bir kod parçasıdır. Temsilci, o kod parçasına işaret eden bir işaretçidir. Bir delege onu işaret etmeden ahlaksız bir yönteme sahip olamazsınız, aksi takdirde asla çağrılmaz. Bir lambda, lambda ifadelerini oluşturmak için kullanılan bir operatördür. Lambda ifadeleri çoğunlukla, bir delege tarafından işaret edilecek olan anoymous yöntemlerle sonuçlanır.
Martin Mulder

Aptalca, ama eğer düğmeye basıldığında kullanımını bilmiyorsam bir If ElseIf ifadesi oluştururdum. Aptal ben dedim.
JustJohn

@Pacerier anonim yöntemi C # 2.0'da ve C # 3.0'da tanıtılan Lambda, ilk olarak Lambda tanıtılsaydı, anonim yöntemler ve hatta delege asla olmazdı!
AminM

18

Genel Listeler için temsilcilerin yaygın kullanımlarından biri, tek satırlı foreach işlemi oluşturmak için Eylem temsilcileridir (veya anonim eşdeğeri):

myList.Foreach( i => i.DoSomething());

Predicate temsilcisini bir Listeyi ararken veya kısaltmada oldukça yararlı buluyorum:

myList.FindAll( i => i.Name == "Bob");    
myList.RemoveAll( i => i.Name == "Bob");

Kodun gerekli olmadığını söylediğini biliyorum, ancak yararlılığını kod aracılığıyla ifade etmeyi daha kolay buluyorum. :)


13

Olayları Olay İşleyicilere Bağlamak, genellikle temsilcilerle ilk tanışmanızdır ... Temsilci EventHandler sınıfına sarıldığı için onları kullandığınızı bile bilmiyor olabilirsiniz.


5

Temsilci modelinin gerçek dünya kodunda nasıl kullanıldığını görmekle ilgileniyorsanız, Mac OS X'te Cocoa'dan başka bir yere bakmayın. Cocoa, Apple'ın Mac OS X altında programlama için tercih ettiği UI araç setidir ve Hedef C'de kodlanmıştır. Her bir UI bileşeninin, alt sınıflandırma veya başka yollardan ziyade yetkilendirme yoluyla genişletilmesi amaçlanacak şekilde tasarlanmıştır.

Daha fazla bilgi için, Apple'ın delegeler hakkında söylediklerine buradan göz atmanızı öneririm .


5

Win32 Python kullanan bir projem vardı.

Çeşitli nedenlerden dolayı, bazı modüller DB'ye erişmek için odbc.py'yi ve diğer modülleri (pyodbc.py) kullandı.

Bir işlevin her iki tür modül tarafından kullanılması gerektiğinde bir sorun vardı. Bir argüman olarak kendisine iletilen bir bağlantı nesnesi vardı, ancak daha sonra zamanları temsil etmek için dbi.dbiDate veya datetime kullanılıp kullanılmayacağını bilmek zorundaydı.

Bunun nedeni odbc.py'nin SQL deyimlerindeki değerler olarak dbi.dbiDate olarak tarih beklemesiydi, oysa pyodbc.py tarih saat değerleri bekleniyordu.

Bir başka zorluk da odbc.py ve pyodbc.py tarafından oluşturulan bağlantı nesnelerinin ek alanlar ayarlamasına izin vermemesiydi.

Benim çözümüm, odbc.odbc (...) ve pyodbc.pyodbc (...) tarafından döndürülen bağlantı nesnelerini, ekstra bir alanın değeri olarak istenen zaman gösterimi işlevini içeren ve hangi delegelerin diğer tüm alan istekleri orijinal bağlantı nesnesine.


5

Seninle aynı soruyu sormuştum ve bir cevap için bu siteye gittim.

Görünüşe göre, bu konudaki örnekleri gözden geçirmeme rağmen daha iyi anlamadım.

Artık delegeler için harika bir kullanım buldum: http://www.c-sharpcorner.com/UploadFile/thiagu304/passdata05172006234318PM/passdata.aspx

Bu, yeni kullanıcılar için daha açık görünebilir çünkü Forms, değerleri aktarmak için POST / GET (QueryString) ile ASP.NET web sitelerinden çok daha karmaşıktır.

Temel olarak, "TextBox metni " ni parametre olarak alan bir temsilci tanımlarsınız .

// Form1

// Class Property Definition
public delegate void delPassData(TextBox text);


// Click Handler
private void btnSend_Click(object sender, System.EventArgs e)
{
     Form2 frm= new Form2();
     delPassData del=new delPassData(frm.funData);
     del(this.textBox1);
     frm.Show();
}

// ÖZET: Temsilci tanımlayın, yeni Form2 sınıfını örnekleyin, temsilciye funData () işlevi atayın, textBox'ınızı temsilciye iletin. Formu gösterin.

// Form2

public void passData(TextBox txtForm1)
{

     label1.Text = txtForm1.Text;
}

// ÖZET: TextBox txtForm1'i parametre olarak (temsilcinizde tanımlandığı şekilde) almanız ve textBox'ın metnine etiket metni atamanız yeterlidir.

Umarım bu, delegelerin bazı kullanımlarını aydınlatır :) ..


Form2 sınıf yönteminin (passData yerine) funData olarak adlandırılması veya Form1 işlev atamasının frm.passData (frm.funData yerine) olarak adlandırılması gerekir.
ethan

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.