Temsilcileri Kullanma (C# Programlama Kılavuzu)

Temsilci, C ve C++ içindeki işlev işaretçisine benzer şekilde bir yöntemi güvenli bir şekilde kapsülleyen bir türdür. C işlevi işaretçilerinden farklı olarak, temsilciler nesne odaklı, tür güvenli ve güvenlidir. Temsilci türü, temsilcinin adıyla tanımlanır. Aşağıdaki örnek, bir dizeyi bağımsız değişken olarak alan ve void döndüren bir yöntemi kapsülleyebilecek adlı Callback bir temsilci bildirir:

public delegate void Callback(string message);

Temsilci nesnesi normalde temsilcinin kaydıracağı yöntemin adı sağlanarak veya bir lambda ifadesiyle oluşturulur. Bir temsilci bu şekilde örneklendirildikten sonra çağrılabilir. Bir temsilciyi çağırmak, temsilci örneğine eklenen yöntemi çağırır. Çağıran tarafından temsilciye geçirilen parametreler yöntemine geçirilir ve varsa yöntemden döndürülen değer, temsilci tarafından çağırana döndürülür. Örneğin:

// Create a method for a delegate.
public static void DelegateMethod(string message)
{
    Console.WriteLine(message);
}
// Instantiate the delegate.
Callback handler = DelegateMethod;

// Call the delegate.
handler("Hello World");

Temsilci türleri .NET'teki sınıfından Delegate türetilir. Temsilci türleri korumalıdır; türetilemezler ve 'den Delegateözel sınıflar türetmek mümkün değildir. Örnek olarak atanan temsilci bir nesne olduğundan, bağımsız değişken olarak geçirilebilir veya bir özelliğe atanabilir. Bu, bir yöntemin bir temsilciyi parametre olarak kabul etmesine ve daha sonra temsilciyi çağırmasına olanak tanır. Bu, zaman uyumsuz geri çağırma olarak bilinir ve uzun bir işlem tamamlandığında çağıranı bilgilendirmenin yaygın bir yöntemidir. Bir temsilci bu şekilde kullanıldığında, temsilciyi kullanan kodun kullanılan yöntemin uygulanması hakkında herhangi bir bilgiye ihtiyacı yoktur. İşlev, kapsülleme arabirimlerinin sağladığına benzer.

Geri çağırmaların bir diğer yaygın kullanımı, özel bir karşılaştırma yöntemi tanımlamak ve bu temsilciyi bir sıralama yöntemine geçirmektir. Çağıranın kodunun sıralama algoritmasının bir parçası olmasını sağlar. Aşağıdaki örnek yöntem, türünü parametre olarak kullanır Del :

public static void MethodWithCallback(int param1, int param2, Callback callback)
{
    callback("The number is: " + (param1 + param2).ToString());
}

Daha sonra yukarıda oluşturulan temsilciyi bu yönteme geçirebilirsiniz:

MethodWithCallback(1, 2, handler);

ve konsola aşağıdaki çıkışı alın:

The number is: 3

Temsilciyi soyutlama olarak kullanmak, MethodWithCallback konsolu doğrudan çağırmak zorunda değildir; bir konsol düşünülerek tasarlanması gerekmez. Tek MethodWithCallback yapmanız gereken bir dize hazırlamak ve dizeyi başka bir yönteme geçirmektir. Bu özellikle güçlüdür çünkü temsilci olarak atanan bir yöntem herhangi bir sayıda parametre kullanabilir.

Bir örnek yöntemini sarmalamak için bir temsilci oluşturulduğunda, temsilci hem örneğe hem de yönteme başvurur. Bir temsilci, kaydırdığı yöntemin dışında örnek türü hakkında bilgi sahibi değildir, bu nedenle temsilci, bu nesne üzerinde temsilci imzası ile eşleşen bir yöntem olduğu sürece herhangi bir nesne türüne başvurabilir. Bir temsilci statik bir yöntemi sarmalamak için oluşturulduğunda, yalnızca yöntemine başvurur. Aşağıdaki bildirimleri dikkate alın:

public class MethodClass
{
    public void Method1(string message) { }
    public void Method2(string message) { }
}

Daha önce gösterilen statik DelegateMethod ile birlikte artık bir Del örnek tarafından sarmalanabilen üç yöntemimiz var.

Bir temsilci çağrıldığında birden fazla yöntem çağırabilir. Bu, çok noktaya yayın olarak adlandırılır. Temsilcinin yöntem listesine (çağırma listesi) ek bir yöntem eklemek için, toplama veya ekleme atama işleçlerini ('+' veya '+=' kullanarak iki temsilci eklenmesi yeterlidir. Örneğin:

var obj = new MethodClass();
Callback d1 = obj.Method1;
Callback d2 = obj.Method2;
Callback d3 = DelegateMethod;

//Both types of assignment are valid.
Callback allMethodsDelegate = d1 + d2;
allMethodsDelegate += d3;

Bu noktada allMethodsDelegate çağrı listesinde üç yöntem bulunur:Method1 , Method2ve DelegateMethod. Özgün üç temsilci ( d1, d2ve d3) değişmeden kalır. Çağrıldığında allMethodsDelegate , üç yöntem de sırayla çağrılır. Temsilci başvuru parametrelerini kullanıyorsa, başvuru sırayla üç yöntemin her birine sırayla geçirilir ve bir yöntemle yapılan tüm değişiklikler sonraki yönteme görünür. Yöntemlerden herhangi biri yönteminde yakalanmayan bir özel durum oluşturursa, bu özel durum temsilcinin çağırıcısına geçirilir ve çağırma listesinde sonraki hiçbir yöntem çağrılmaz. Temsilcinin dönüş değeri ve/veya out parametreleri varsa, çağrılan son yöntemin dönüş değerini ve parametrelerini döndürür. Bir yöntemi çağırma listesinden kaldırmak için çıkarma veya çıkarma atama işleçlerini (- veya -=) kullanın. Örneğin:

//remove Method1
allMethodsDelegate -= d1;

// copy AllMethodsDelegate while removing d2
Callback oneMethodDelegate = allMethodsDelegate - d2;

Temsilci türleri öğesinden System.Delegatetüretildiğinden, bu sınıf tarafından tanımlanan yöntemler ve özellikler temsilcide çağrılabilir. Örneğin, bir temsilcinin çağırma listesinde yöntem sayısını bulmak için şunları yazabilirsiniz:

int invocationCount = d1.GetInvocationList().GetLength(0);

Çağırma listelerinde birden fazla yöntemi olan temsilciler, alt sınıfı System.Delegateolan 'den MulticastDelegatetüretilir. Her iki sınıf da desteklediğinden GetInvocationListyukarıdaki kod her iki durumda da çalışır.

Çok noktaya yayın temsilcileri olay işlemede kapsamlı olarak kullanılır. Olay kaynağı nesneleri, bu olayı almak üzere kaydedilmiş alıcı nesnelere olay bildirimleri gönderir. Bir olaya kaydolmak için, alıcı olayı işlemek üzere tasarlanmış bir yöntem oluşturur, ardından bu yöntem için bir temsilci oluşturur ve temsilciyi olay kaynağına geçirir. Olay gerçekleştiğinde kaynak temsilciyi çağırır. Temsilci daha sonra olay verilerini teslim ederek alıcı üzerinde olay işleme yöntemini çağırır. Belirli bir olayın temsilci türü, olay kaynağı tarafından tanımlanır. Daha fazla bilgi için bkz . Olaylar.

Derleme zamanında atanan iki farklı türde temsilcinin karşılaştırılması derleme hatasına neden olur. Temsilci örnekleri statik olarak türündeyse System.Delegate, karşılaştırmaya izin verilir, ancak çalışma zamanında false döndürür. Örneğin:

delegate void Callback1();
delegate void Callback2();

static void method(Callback1 d, Callback2 e, System.Delegate f)
{
    // Compile-time error.
    //Console.WriteLine(d == e);

    // OK at compile-time. False if the run-time type of f
    // is not the same as that of d.
    Console.WriteLine(d == f);
}

Ayrıca bkz.