İşlevsel dillerde (lisp gibi), listedeki belirli bir öğeye ne olacağını belirlemek için desen eşleştirme kullanırsınız. C # 'daki eşdeğeri, bir öğenin türünü kontrol eden ve buna dayalı bir işlem gerçekleştiren if ... elseif deyimlerinin bir zinciri olacaktır. Söylemeye gerek yok, fonksiyonel kalıp eşleme, çalışma zamanı tip kontrolünden daha etkilidir.
Polimorfizm kullanmak, desen eşleşmesine daha yakın bir eşleşme olacaktır. Diğer bir deyişle, bir listenin nesnelerinin belirli bir arabirimle eşleşmesi ve bu arabirimde her nesne için bir işlev çağrılması. Başka bir alternatif, belirli bir nesne türünü parametre olarak alan bir dizi aşırı yüklenmiş yöntem sağlamak olacaktır. Object'i parametre olarak alan varsayılan yöntem.
public class ListVisitor
{
public void DoSomething(IEnumerable<dynamic> list)
{
foreach(dynamic obj in list)
{
DoSomething(obj);
}
}
public void DoSomething(SomeClass obj)
{
//do something with SomeClass
}
public void DoSomething(AnotherClass obj)
{
//do something with AnotherClass
}
public void DoSomething(Object obj)
{
//do something with everything els
}
}
Bu yaklaşım Lisp patern eşleşmesine bir yaklaşım sağlar. Ziyaretçi kalıbı (burada uygulandığı gibi heterojen listeler için mükemmel bir kullanım örneğidir). Başka bir örnek, öncelik sırasındaki belirli mesajların dinleyicilerinin bulunduğu ve sorumluluk zincirini kullanan mesaj dağıtımına, dağıtım görevlisinin mesajı ilettiği ve mesajla eşleşen ilk işleyicinin onu ele aldığı durumdur.
Kapak tarafı, bir mesaj için kayıt yaptıran herkese bildirimde bulunur (örneğin, MVVM modelinde ViewModellerin gevşek bağlantısı için yaygın olarak kullanılan Olay Toplayıcı modeli). Aşağıdaki yapıyı kullanıyorum
IDictionary<Type, List<Object>>
Sözlüğe eklemenin tek yolu bir işlevdir
Register<T>(Action<T> handler)
(ve nesne aslında iletilen işleyiciye bir WeakReference). İşte burada <Object> Listesini kullanmak zorundayım çünkü derleme zamanında kapalı tipin ne olacağını bilmiyorum. Ancak Runtime anda sözlük için anahtar o Tür olacağını zorlayabilirsiniz. Aradığım olayı başlatmak istediğimde
Send<T>(T message)
ve listeyi tekrar çözüyorum. Listeyi <dynamic> kullanmanın bir avantajı yok çünkü zaten yayınlamam gerekiyor. Gördüğünüz gibi her iki yaklaşımın da avantajları var. Yöntem aşırı yüklemesi kullanarak bir nesneyi dinamik olarak gönderecekseniz, dinamik bunu yapmanın yoludur. Ne olursa olsun yayınlamak için ZORUNLU iseniz, Object de kullanabilirsiniz.