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

Önceki

Bu makalede, .NET'te temsilcileri destekleyen sınıflar ve bunların anahtar sözcükle nasıl eşlen olduğu delegate açıklanmıştır.

Temsilci türlerini tanımlama

'delegate' anahtar sözcüğüyle başlayalım çünkü temsilcilerle birlikte çalışmada öncelikli olarak bunu kullanıcaz. Anahtar sözcüğünü kullanırken derleyicinin oluşturlediği kod, ve sınıflarının delegate üyelerini çağıran yöntem çağrılarına Delegate MulticastDelegate eşler.

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

Örneğimizde List.Sort() yöntemini kullanmaya devam edeceğiz. İlk adım karşılaştırma temsilcisi için bir tür oluşturmak olacak:

// 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 sınıfından türetilen bir sınıf oluşturur (bu durumda, bir tamsayı döndüren ve System.Delegate iki bağımsız değişkeni olan bir yöntem). Bu temsilcinin türü: Comparison . Temsilci Comparison türü genel bir tür. Genel türler hakkında ayrıntılı bilgi için buraya bakın.

Söz dizimi, bir değişken bildirıyor gibi görünebilir ancak aslında bir türü bildirer. Temsilci türlerini sınıfların içinde, doğrudan ad alanlarının içinde, hatta genel ad alanı içinde tanımlayabilirsiniz.

Not

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

Derleyici ayrıca bu yeni tür için ekleme ve kaldırma işleyicileri de üretir, böylece bu sınıfın istemcileri bir örneğin çağırma listesinden yöntemler ekleyebilir ve kaldırabilir. Derleyici, eklenen veya kaldırılan yöntemin imzasının yöntemi bildirerek kullanılan imzayla eşleşmesi için zorlar.

Temsilci örneklerini bildir

Temsilciyi tanımlayarak bu tür bir örnek oluşturabilirsiniz. C# içinde tüm değişkenler gibi, temsilci örneklerini doğrudan bir ad alanına veya genel ad alanına bildiramazsınız.

// inside a class definition:

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

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

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

Temsilcileri çağırma

Bir temsilcinin çağırma listesinde yer alan yöntemleri bu temsilciyi çağırarak çağırırsiniz. yönteminin Sort() içinde kod, nesneleri hangi sıranın içine yerley karartacak şekilde karşılaştırma yöntemini çağıracak:

int result = comparator(left, right);

Yukarıdaki satırda, kod temsilciye bağlı yöntemini çağırır. Değişkeni yöntem adı olarak işler ve normal yöntem çağrısı söz dizimi kullanarak çağırırsanız.

Bu kod satırı güvenli olmayan bir varsayımda bulundu: Temsilciye bir hedefin eklenmiştir garantisi yoktur. Hiçbir hedef ekli yoksa, yukarıdaki satır bir NullReferenceException atılan neden olur. Bu sorunu çözmek için kullanılan deyimler, basit bir null denetimden daha karmaşıktır ve bu serinin devamlarında ele almaktadır.

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

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

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

Dize listesini uzunluğuna göre sıralamak istediğini 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 bildirildi. Bu sorun değil. Bu yöntemin genel arabiriminizin bir parçası olması istemeyebilirsiniz. Bir temsilciye ekli olduğunda karşılaştırma yöntemi olarak yine de kullanılabilir. Çağıran kodun bu yöntemi temsilci nesnesinin hedef listesine eklenir ve bu temsilci aracılığıyla bu yönteme erişebilirsiniz.

Bu ilişkiyi oluşturmak için bu yöntemi yöntemine geçirmeniz List.Sort() gerekir:

phrases.Sort(CompareLength);

Yöntem adının parantez olmadan kullanılmıştır. yöntemini bağımsız değişken olarak kullanmak, derleyiciye yöntem başvurularını temsilci çağırma hedefi olarak kullanılan bir başvuruya dönüştürmelerini ve bu yöntemi bir çağırma hedefi olarak eklemelerini söyler.

Ayrıca, türünde bir değişken bildirerek ve bir atama yaparak da Comparison<string> açık olabilirsiniz:

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 ifadesi söz dizimi yaygındır:

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

Temsilci hedefleri için lambda ifadeleri kullanmak sonraki bir bölümde daha fazla ele almaktadır.

Sort() örneği genellikle temsilciye tek bir hedef yöntem iliştirer. Ancak, temsilci nesneleri bir temsilci nesnesine eklenmiş birden çok hedef yöntemi olan çağırma listelerini destekler.

Delegate ve MulticastDelegate sınıfları

Yukarıda açıklanan dil desteği, normalde temsilcilerle çalışmak için ihtiyacınız olan özellikleri ve desteği sağlar. Bu özellikler .NET Core çerçevesindeki iki sınıf üzerinde yerleşiktir: Delegate ve MulticastDelegate .

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

İlginç olan, System.Delegate ve System.MulticastDelegate sınıfların kendileri temsilci türleri değildir. Belirli tüm temsilci türleri için temel sağlarlar. Aynı dil tasarımı işlemi, veya 'den türeten bir sınıf bildirileyemayamaz. Delegate MulticastDelegate C# dil kuralları bunu yasaklar.

Bunun yerine C# derleyicisi, temsilci türlerini bildiren C# dil anahtar sözcüğünü kullanarak MulticastDelegate türetilen bir sınıfın örneklerini oluşturur.

Bu tasarımın kökleri C# ve .NET'in ilk sürümüne sahiptir. Tasarım ekibinin hedeflerinden biri, temsilciler kullanırken dilin tür güvenliğini zorunlu kılınmasıdır. Bu, temsilcilerin doğru tür ve bağımsız değişken sayısıyla çağrılmalarını sağlamak anlamına geldi. Ayrıca, herhangi bir dönüş türünün derleme zamanında doğru şekilde belirtilmiş olduğunu. Temsilciler, genel türlerden önceki 1.0 .NET sürümüne katıldı.

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ıdır.

Türetilmiş sınıfları doğrudan oluşturamazken, bu sınıflarda tanımlanan yöntemleri kullanabilirsiniz. Şimdi temsilcilerle birlikte çalışmada en yaygın yöntemlerin üzerinden geçebilirsiniz.

Anımsanacak en önemli ilk gerçek, birlikte çalışmakta olan her temsilcinin 'den türetilen MulticastDelegate olmasıdır. Çok noktaya yayın temsilcisi, bir temsilci aracılığıyla çağrılırken birden fazla yöntem hedefinin çağrılY olduğu anlamına gelir. Özgün tasarımda, yalnızca bir hedef yöntemin ekli ve çağrılması gereken temsilciler ile birden çok hedef yöntemin ekli ve çağrılması gereken temsilciler arasında ayrım yapma düşünülebilir. Bu ayrım, başlangıçtaki düşünceye göre pratikte daha az yararlı olduğu kanıtlandı. İki farklı sınıf zaten oluşturulmuş ve ilk genel yayından bu yana çerçevede yer alan sınıftır.

Temsilcilerle en çok kullanabileceğiniz yöntemler ve Invoke() BeginInvoke() / EndInvoke() yöntemleridir. Invoke() , belirli bir temsilci örneğine eklenmiş olan tüm yöntemleri çağırır. Yukarıda da gördüğümüz gibi, temsilci değişken üzerindeki yöntem çağrısı söz dizimlerini kullanarak genellikle temsilcileri çağırırsanız. Bu serinin devamlarında göreceğiniz gibi,bu yöntemlerle doğrudan çalışacak desenler vardır.

Dil söz dizimlerini ve temsilcileri destekleyen sınıfları gördünüz. Şimdi, türü kesin olarak yazılan temsilcilerin ne kadar güçlü şekilde kullanıldıklarına, oluşturulduklarına ve çağrıldılarına bakalım.

Sonraki