System.Delegate ve delegate anahtar sözcüğü

Geri

Bu makale, .NET'te temsilcileri destekleyen sınıfları ve bu sınıfların anahtar sözcükle nasıl eşlendiğini delegate kapsar.

Temsilci türlerini tanımlama

Öncelikle temsilcilerle çalışırken kullanacağınız anahtar sözcük bu olduğundan , 'delegate' anahtar sözcüğüyle başlayalım. anahtar sözcüğünü kullandığınızda delegate derleyicinin oluşturduğu kod, ve MulticastDelegate sınıflarının üyelerini çağıran yöntem çağrılarıyla Delegate eşlenir.

Yöntem imzası tanımlamaya benzer bir söz dizimi kullanarak bir temsilci türü tanımlarsınız. Yalnızca anahtar sözcüğünü delegate tanıma eklersiniz.

Örneğimiz olarak List.Sort() yöntemini kullanmaya devam edelim. İlk adım, karşılaştırma temsilcisi için bir tür oluşturmaktır:

// From the .NET Core library

// Define the delegate type:
public delegate int Comparison<in T>(T left, T right);

Derleyici, kullanılan imzayla eşleşen bir System.Delegate sınıf oluşturur (bu örnekte tamsayı döndüren ve iki bağımsız değişkeni olan bir yöntem). Bu temsilcinin türü şeklindedir Comparison. Temsilci Comparison türü genel bir türdür. Genel bilgiler için buraya bakın.

Söz diziminin bir değişken bildiriyormuş gibi görünebileceğine, ancak aslında bir tür bildirdiğine dikkat edin. Temsilci türlerini sınıfların içinde, doğrudan ad alanlarının içinde, hatta genel ad alanında tanımlayabilirsiniz.

Not

Temsilci türlerinin (veya diğer türlerin) doğrudan genel ad alanında bildirilmesi önerilmez.

Derleyici ayrıca bu yeni tür için ek ve kaldır işleyicileri oluşturur, böylece bu sınıfın istemcileri bir örneğin çağrı listesinden yöntem ekleyebilir ve kaldırabilir. Derleyici, eklenen veya kaldırılan yöntemin imzasının yöntemi bildirirken kullanılan imzayla eşleşmesini zorlar.

Temsilcilerin örneklerini bildirme

Temsilciyi tanımladıktan sonra bu tür bir örnek oluşturabilirsiniz. C# içindeki tüm değişkenler gibi, temsilci örneklerini doğrudan bir ad alanında veya genel ad alanında bildiremezsiniz.

// inside a class definition:

// Declare an instance of that type:
public Comparison<T> comparator;

Değişkenin türü, daha önce tanımlanan temsilci türüdür Comparison<T>. değişkeninin adıdır comparator.

Yukarıdaki kod parçacığı bir sınıfın içinde bir üye değişkeni bildirdi. Ayrıca, yerel değişkenler olan temsilci değişkenleri veya yöntemler için bağımsız değişkenler de bildirebilirsiniz.

Temsilcileri çağırma

Bu temsilciyi çağırarak bir temsilcinin çağrı listesinde yer alan yöntemleri çağırırsınız. yönteminin Sort() içinde kod, nesnelerin yerleştirileceği sırayı belirlemek için karşılaştırma yöntemini çağırır:

int result = comparator(left, right);

Yukarıdaki satırda kod , temsilciye eklenmiş yöntemi çağırır . Değişkeni bir yöntem adı olarak ele alır ve normal yöntem çağrısı söz dizimini kullanarak çağırırsınız.

Bu kod satırı güvenli olmayan bir varsayımda bulunur: Temsilciye bir hedef eklendiğinin garantisi yoktur. Hiçbir hedef iliştirilmemişse, yukarıdaki satır bir NullReferenceException atılması neden olabilir. Bu sorunu gidermek için kullanılan deyimler basit bir null denetiminden daha karmaşıktır ve bu serinin ilerleyen bölümlerinde ele alınmıştır.

Çağırma hedeflerini atama, ekleme ve kaldırma

Temsilci türü bu şekilde tanımlanır ve temsilci örnekleri nasıl bildirilir ve çağrılır.

yöntemini kullanmak isteyen geliştiricilerin List.Sort() , imzası temsilci türü tanımıyla eşleşen bir yöntem tanımlaması ve sıralama yöntemi tarafından kullanılan temsilciye ataması gerekir. Bu atama yöntemini bu temsilci nesnesinin çağrı listesine ekler.

Dizelerin listesini uzunluklarına göre sıralamak istediğinizi varsayalım. Karşılaştırma işleviniz aşağıdaki gibi olabilir:

private static int CompareLength(string left, string right) =>
    left.Length.CompareTo(right.Length);

yöntemi özel bir yöntem olarak bildirilir. Sorun değil. Bu yöntemin ortak arabiriminizin bir parçası olmasını istemeyebilirsiniz. Yine de bir temsilciye eklendiğinde karşılaştırma yöntemi olarak kullanılabilir. Çağıran kod, temsilci nesnesinin hedef listesine bu yöntemi ekler ve bu temsilci aracılığıyla bu yönteme erişebilir.

Bu yöntemi yöntemine geçirerek bu ilişkiyi List.Sort() oluşturursunuz:

phrases.Sort(CompareLength);

Yöntem adının parantez olmadan kullanıldığına dikkat edin. yöntemini bağımsız değişken olarak kullanmak, derleyiciye yöntem başvurularını temsilci çağırma hedefi olarak kullanılabilecek bir başvuruya dönüştürmesini ve bu yöntemi çağırma hedefi olarak eklemesini söyler.

Ayrıca türündeki Comparison<string> bir değişkeni bildirerek ve atama yaparak da açıklayabilirdiniz:

Comparison<string> comparer = CompareLength;
phrases.Sort(comparer);

Temsilci hedefi olarak kullanılan yöntemin küçük bir yöntem olduğu kullanımlarda, atamayı gerçekleştirmek için lambda ifadesinin söz dizimini kullanmak yaygın bir yöntemdir:

Comparison<string> comparer = (left, right) => left.Length.CompareTo(right.Length);
phrases.Sort(comparer);

Temsilci hedefleri için lambda ifadelerinin kullanılması daha sonraki bir bölümde ele alınmıştır.

Sort() örneği genellikle temsilciye tek bir hedef yöntemi ekler. Ancak, temsilci nesneleri, bir temsilci nesnesine bağlı birden çok hedef yöntemi olan çağırma listelerini destekler.

Temsilci ve Çok Noktaya YayınDelegate sınıfları

Yukarıda açıklanan dil desteği genellikle temsilcilerle çalışmanız gereken özellikleri ve desteği sağlar. Bu özellikler .NET Core çerçevesinde iki sınıfa dayalıdır: Delegate ve MulticastDelegate.

System.Delegate sınıfı ve tek doğrudan alt sınıfı, System.MulticastDelegatetemsilci oluşturmak, yöntemleri temsilci hedefleri olarak kaydetmek ve temsilci hedefi olarak kaydedilen tüm yöntemleri çağırmak için çerçeve desteği sağlar.

İlginç bir şekilde, System.Delegate ve System.MulticastDelegate sınıfları kendileri temsilci türleri değildir. Tüm belirli temsilci türleri için temel sağlar. veya öğesinden DelegateMulticastDelegatetüretilen bir sınıf bildiremeyeceğiniz aynı dil tasarım işlemi zorunlu kılındı. C# dil kuralları bunu yasaklar.

Bunun yerine, C# derleyicisi, temsilci türlerini bildirmek için C# dil anahtar sözcüğünü kullandığınızda türetilen MulticastDelegate bir sınıfın örneklerini oluşturur.

Bu tasarımın kökleri C# ve .NET'in ilk sürümündedir. Tasarım ekibi için hedeflerden biri, temsilciler kullanılırken dilin tür güvenliğini zorunlu kılmasını sağlamaktı. Bu, temsilcilerin doğru türde ve sayıda bağımsız değişkenle çağrılmasını sağlamak anlamına geliyordu. Ve herhangi bir dönüş türünün derleme zamanında doğru şekilde belirtildiğini. Temsilciler, genel sürümlerden önceki 1.0 .NET sürümünün bir parçasıydı.

Bu tür güvenliği zorlamanın en iyi yolu, derleyicinin kullanılan yöntem imzasını temsil eden somut temsilci sınıflarını oluşturmasıydı.

Türetilmiş sınıfları doğrudan oluşturamasanız da, bu sınıflarda tanımlanan yöntemleri kullanırsınız. Şimdi temsilcilerle çalışırken kullanacağınız en yaygın yöntemleri inceleyelim.

Hatırlamanız gereken ilk, en önemli gerçek, birlikte çalıştığınız her temsilcinin 'den MulticastDelegatetüretilmiş olmasıdır. Çok noktaya yayın temsilcisi, bir temsilci aracılığıyla çağrılırken birden fazla yöntem hedefinin çağrılabileceği anlamına gelir. Özgün tasarım, yalnızca bir hedef yöntemin eklenip çağrılabildiği temsilciler ile birden çok hedef yöntemin eklenip çağrılabileceği temsilciler arasında ayrım yapmayı göz önünde bulunduruldu. Bu ayrım pratikte başlangıçtaki düşünceden daha az yararlı oldu. İki farklı sınıf zaten oluşturulmuştur ve ilk genel sürümünden bu yana çerçevededir.

Temsilcilerle en çok kullanacağınız yöntemler ve BeginInvoke() / EndInvoke()şeklindedir.Invoke() Invoke() , belirli bir temsilci örneğine eklenmiş olan tüm yöntemleri çağırır. Yukarıda gördüğünüz gibi, genellikle temsilci değişkeninde yöntem çağrısı söz dizimini kullanarak temsilcileri çağırırsınız. Bu serinin devamında göreceğiniz gibi, doğrudan bu yöntemlerle çalışan desenler vardır.

Dil söz dizimini ve temsilcileri destekleyen sınıfları gördüğünüze göre, şimdi türü kesin olarak belirlenmiş temsilcilerin nasıl kullanıldığını, oluşturulduğunu ve çağrıldığı inceleyelim.

İleri