Как да отпиша абонамент за анонимна функция в метод Dispose на клас?

Имам клас A... в неговия конструктор... присвоявам анонимна функция на eventHandler на Object_B.

Как да премахна (отпиша) това от метода Dispose от клас A?

Всяка помощ ще бъде оценена! Благодаря

Public Class A
{

public A()
 {

 B_Object.DataLoaded += (sender, e) =>
                {
                   Line 1
                   Line 2
                   Line 3
                   Line 4
                };
 }

Public override void Dispose()
{
  // How do I unsubscribe the above subscribed anonymous function ?
}
}

person Relativity    schedule 16.03.2012    source източник
comment
Какво е B_Object? Променлива член от клас A ли е? И има ли достъп навсякъде извън A; може ли да има други слушатели?   -  person Dax Fohl    schedule 17.03.2012
comment
възможен дубликат на Анонимен метод за отписване в C#   -  person Tim Schmelter    schedule 17.03.2012
comment
да, член е...кой екземпляр от клас B   -  person Relativity    schedule 17.03.2012


Отговори (3)


По принцип не можете. Или го преместете в метод, или използвайте членска променлива, за да запазите делегата за по-късно:

public class A : IDisposable
{
    private readonly EventHandler handler;

    public A()
    {
        handler = (sender, e) =>
        {
           Line 1
           Line 2
           Line 3
           Line 4
        };

        B_Object.DataLoaded += handler;
     }

     public override void Dispose()
     {
        B_Object.DataLoaded -= handler;
     }
}
person Jon Skeet    schedule 16.03.2012
comment
Така че, ако не сме се отписали от това... това очевидно ще доведе до изтичане на памет, нали? - person Relativity; 17.03.2012
comment
@Relativity: Не е задължително. Вие наистина не сте говорили за B_Object.DataLoaded - ако това е всъщност събитие на екземпляр, а не статично събитие, тогава ако обектът е събран, абонаментът за събитието вече няма да има значение. Всичко зависи от контекста... - person Jon Skeet; 17.03.2012
comment
B_Object.DataLoaded е събитие на екземпляр...не статично събитие. Бихте ли изяснили това: - ако обектът е събран, абонаментът за събитието няма да има значение - person Relativity; 17.03.2012
comment
@Relativity: Ако обект X се абонира за събития от обект Y, но не се отпише, висящите събития ще накарат обект X да остане в паметта поне толкова дълго, колкото обект Y. Ако животът на паметта на обект Y ще бъде много по-дълъг от полезен живот на обект X, това може да е лошо нещо. Ако по време на живота на паметта на обект Y много екземпляри на обект X бъдат създадени и изоставени, това може да бъде много лошо, ако не и катастрофално. Ако обаче Y отговаря на условията за събиране, когато моментът X стане безполезен, висящият абонамент няма да поддържа X жив. - person supercat; 19.03.2012
comment
@Relativity: Въпреки че висящите абонаменти са безвредни в такива случаи, те все още са неприятни. Наистина ме дразни, че нито vb.net, нито C# предоставят удобно средство за отписване на всички събития, към които е прикачено. - person supercat; 19.03.2012

Правилният начин да направите това е да използвате разширенията Rx. Гледайте видеоклиповете тук:

http://msdn.microsoft.com/en-us/data/gg577611

Намерих "блус" филма за особено полезен.

person Brannon    schedule 16.03.2012

Това е алтернатива без използване на манипулираща променлива.

Public Class A
{

 public A()
  {

    B_Object.DataLoaded += (sender, e) =>
                {
                   Line 1
                   Line 2
                   Line 3
                   Line 4
                };
  }

  Public override void Dispose()
  {
   if(B_Object.DataLoaded != null)
   {
     B_Object.DataLoaded -=
         (YourDelegateType)B_Object.DataLoaded.GetInvocationList().Last();
       //if you are not sure that the last method is yours than you can keep an index
       //which is set in your ctor ...
   }
  }
 }
person Ion Sapoval    schedule 16.03.2012