2010-11-30 25 views
1

J'utilise le modèle expression-builder pour créer un objet. Une des choses que l'expression-constructeur configure sur l'objet est les gestionnaires d'événements. Voici quelques pseudo-code démonstratif:Copier la liste d'invocation d'un délégué à un autre

public class TargetObject 
    { 
     public event Action SomeEvent; 
    } 

    public class ObjectBuilder 
    { 
     private Action handler; 

     public TargetObject GetObject() 
     { 
      TargetObject target = new TargetObject(); 
      target.SomeEvent += handler; 

      return target; 
     } 

     public ObjectBuilder AddHandler(Action handler) 
     { 
      this.handler += handler; 
      return this; 
     } 
    } 

Ce que je voudrais est, plutôt que d'écrire:

this.handler += handler; 

Pour transférer l'appel liste encapsulé par le « gestionnaire » membre ObjectBuilder, à " SomeEvent "dans la cible. Dans le cas contraire, ObjectBuilder ne sera pas récupéré par le garbage car "SomeEvent" de mon TargetObject contiendra une référence au "handler" de l'ObjectBuilder.

Est-ce possible?

EDIT: Comme demandé, voici quelques exemples de code qui consomme ces classes:

class Program 
    { 
     static void Main(string[] args) 
     { 
      TargetObject target = new ObjectBuilder() 
       .AddHandler(DoSomething) 
       .GetObject(); 
     } 

     private static void DoSomething() 
     { 
     } 
    } 
+0

Les deux objets sont-ils du même type? –

+0

Quels sont les deux objets ?? – joniba

+0

Un délégué est un type de référence immuable. Le 'TargetObject' renvoyé n'empêchera pas l'instance' ObjectBuilder' qui l'a créé d'être GCed. Le champ 'handler' contient une * référence * à une instance de délégué * ailleurs * sur le tas. Cette référence est * copiée * lorsque vous faites 'target.SomeEvent + = handler;' En d'autres termes, 'target' n'a aucune connaissance de ce' ObjectBuilder' du tout, et ne contiendra pas de référence, directement ou par l'intermédiaire de son (probablement) délégué-champ pour son gestionnaire d'événements. – Ani

Répondre

0

Êtes-vous sûr ObjectBuilder n'est pas GC-ed, car par exemple TargetObject tient son champ "gestionnaire"? delegate est immutable, this.handler + = handler créera une nouvelle instance d'Action.

+0

S'il vous plaît voir mon dernier commentaire en réponse au commentaire d'Ani. Vous avez raison qu'une nouvelle instance de délégué est créée, mais cette nouvelle instance fait référence à un membre de l'instance ObjectBuilder. – joniba

+0

@joniba: J'ai écrit une application de test et je n'ai trouvé aucune fuite en utilisant Memory Profiler. –