SORU
15 Kasım 2008, CUMARTESİ


Ne kadar doğru bir olay işleyicisi kaldırmak için

Kod Gözden Geçirme, bu (basitleştirilmiş) kod parçası, bir olay işleyicisi kaydını buldum:

 Fire -= new MyDelegate(OnFire);

Bu daha önce kayıtlı olan yeni bir temsilci yaratır çünkü olay işleyicisi kaydı değil diye düşündüm. Ama MSDN ben ararken bu tabiri kullanan bazı kod örnekleri buldum.

Bir deney başladım:

internal class Program
{
    public delegate void MyDelegate(string msg);
    public static event MyDelegate Fire;

    private static void Main(string[] args)
    {
        Fire  = new MyDelegate(OnFire);
        Fire  = new MyDelegate(OnFire);
        Fire("Hello 1");
        Fire -= new MyDelegate(OnFire);
        Fire("Hello 2");
        Fire -= new MyDelegate(OnFire);
        Fire("Hello 3");
    }

    private static void OnFire(string msg)
    {
        Console.WriteLine("OnFire: {0}", msg);
    }

}

Benim için sürpriz oldu, şu oldu:

  1. Fire("Hello 1"); beklendiği gibi iki mesaj üretilir.
  2. Fire("Hello 2"); bir mesaj çıkardı.< / ^ br . Bu new delegeler kaydını çalışıyor o beni ikna etti!
  3. Fire("Hello 3"); NullReferenceException bir attı.< / ^ br . Kod hata ayıklama Fire null olay kaydı siliniyor sonra olduğunu gösterdi.

Olay işleyicileri ve temsilci için, derleyici sahne arkasında bir sürü kod oluşturur biliyorum. Ama ben hala benim akıl yanlış olduğunu anlamıyorum.

Neyi kaçırıyorum?

Ek soru: Fire olaylar kayıtlı hiç bir zaman ** 16 yaşında olduğu için, her yerde bir olay harekete geçirilen sonuçlandırmak, null karşı bir kontrol gereklidir.

CEVAP
15 Kasım 2008, CUMARTESİ


C# derleyicisi işleyicisi çağırır bir olay çıkarırken Delegate.Combine, bir olay işleyicisi Delegate.Remove çağrı ekleme varsayılan uygulama:

Fire = (MyDelegate) Delegate.Remove(Fire, new MyDelegate(Program.OnFire));

Delegate.Remove Çerçevesinde uygulanması MyDelegate nesnenin kendisi bakmıyor, ama bu yöntem de temsilci (Program.OnFire) anlamına gelir. Böylece, güvende varolan bir olay işleyicisi aboneliği ne zaman MyDelegate yeni bir nesne oluşturmak için. Çünkü bu, C# derleyicisi kullanın bir steno sözdizimi (o üretir tam olarak aynı kodu sahne arkasında) ekleme/çıkarma olay işleyicileri: atlarsanız new MyDelegate bölüm:

Fire  = OnFire;
Fire -= OnFire;

Son temsilci olay işleyicisi kaldırıldığında, 27* *null döndürüyor. Bulduk, artırmadan önce boş karşı olayı kontrol etmek için önemlidir:

MyDelegate handler = Fire;
if (handler != null)
    handler("Hello 3");

Geçici yerel bir değişkene atanmış diğer konuları olay işleyicileri aboneliği ile olası bir yarış durumu karşı savunmak için. (Yerel bir değişken için bir olay işleyicisi atama parçacığı güvenliği ile ilgili ayrıntılar için my blog post bakın.) Başka bir şekilde savunmaya karşı bu sorun oluşturmak için boş bir temsilci her zaman abone; bu süre kullanır biraz daha fazla bellek, olay işleyicisi ... asla boş (ve kod daha basit):

public static event MyDelegate Fire = delegate { };

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • buttheadgsxr1000

    buttheadgsxr

    24 Ocak 2008
  • DigitalRev TV

    DigitalRev T

    30 AĞUSTOS 2007
  • Harvest: Greg Laurie

    Harvest: Gre

    6 HAZİRAN 2006