Класс WeakDelegate, предоставляющий возможность создания "слабых" делегатов - C#

Узнай цену своей работы

Формулировка задачи:

Помогите пожалуйста решить задачку!) При добавлении делегата
Листинг программы
  1. source.ShitHappened += new EventHandler<ShitHappenedEventArgs>(target.Method);
объект source сохраняет ссылку на объект target через экземпляр делегата. Соответственно, объект target не сможет быть освобожден GC, если на объект source сохранились ссылки даже если других ссылок на target нет. Задача: требуется разработать класс WeakDelegate, предоставляющий возможность создания "слабых" делегатов, которые позволяют GC освободить target, если на target нет обычных ссылок (например, через обычные делегаты). Класс WeakDelegаtе должен содержать метод Create с обычным делегатом в качестве параметра, возвращающий "слабый" делегат такого же типа, что и переданный (шаблон Proxy). Если target был освобожден GC, то "слабый делегат" ничего не выполняет (при необходимости возвращает значение или значения по умолчанию). Требуется поддержка делегатов с произвольным числом параметров, с переменным числом параметров, с ref и out параметрами, с возвращаемым значением. Пример:
Листинг программы
  1. source.ShitHappened += (EventHandler<ShitHappenedEventArgs>)WeakDelegate.Create(new EventHandler<ShitHappenedEventArgs>(target.Method));

Решение задачи: «Класс WeakDelegate, предоставляющий возможность создания "слабых" делегатов»

textual
Листинг программы
  1. public class WeakDelegate<TDelegate> where TDelegate : class
  2. {
  3.   class MethodTarget
  4.   {
  5.     public readonly WeakReference Reference;
  6.     public readonly MethodInfo Method;
  7.  
  8.     public MethodTarget (Delegate d)
  9.     {
  10.       Reference = new WeakReference (d.Target);
  11.       Method = d.Method;
  12.     }
  13.   }
  14.  
  15.   List<MethodTarget> _targets = new List<MethodTarget>();
  16.  
  17.   public WeakDelegate()
  18.   {
  19.     if (!typeof (TDelegate).IsSubclassOf (typeof (Delegate)))
  20.       throw new InvalidOperationException
  21.         ("TDelegate must be a delegate type");
  22.   }
  23.  
  24.   public void Combine (TDelegate target)
  25.   {
  26.     if (target == null) return;
  27.  
  28.     foreach (Delegate d in (target as Delegate).GetInvocationList())
  29.       _targets.Add (new MethodTarget (d));
  30.   }
  31.  
  32.   public void Remove (TDelegate target)
  33.   {
  34.     if (target == null) return;
  35.     foreach (Delegate d in (target as Delegate).GetInvocationList())
  36.     {
  37.       MethodTarget mt = _targets.Find (w =>
  38.         d.Target.Equals (w.Reference.Target) &&
  39.         d.Method.MethodHandle.Equals (w.Method.MethodHandle));
  40.  
  41.       if (mt != null) _targets.Remove (mt);
  42.     }
  43.   }
  44.  
  45.   public TDelegate Target
  46.   {
  47.     get
  48.     {
  49.       var deadRefs = new List<MethodTarget>();
  50.       Delegate combinedTarget = null;
  51.  
  52.       foreach (MethodTarget mt in _targets.ToArray())
  53.       {
  54.         WeakReference target = mt.Reference;
  55.         if (target != null && target.IsAlive)
  56.         {
  57.           var newDelegate = Delegate.CreateDelegate (
  58.             typeof (TDelegate), mt.Reference.Target, mt.Method);
  59.            
  60.           combinedTarget = Delegate.Combine (combinedTarget, newDelegate);
  61.         }
  62.         else
  63.           deadRefs.Add (mt);
  64.       }
  65.  
  66.       foreach (MethodTarget mt in deadRefs)   // Remove dead references
  67.         _targets.Remove (mt);                 // from _targets.
  68.  
  69.       return combinedTarget as TDelegate;
  70.     }
  71.     set
  72.     {
  73.       _targets.Clear();
  74.       Combine (value);
  75.     }
  76.   }
  77. }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

11   голосов , оценка 4.091 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы