2009-11-12 4 views
6

J'ai eu du mal à trouver un bon moyen de formuler cette question, alors laissez-moi essayer d'expliquer par l'exemple:Est-ce qu'une référence à un délégué constitue une référence à un objet (pour empêcher la récupération de place)?

Supposons que j'ai une interface. Par souci de simplicité, je dirais que l'interface est IRunnable, et il fournit une seule méthode, Run. (Ce n'est pas réel, c'est seulement un exemple.)

Maintenant, supposons que j'ai une classe pré-existante, appelons-la Cheetah, que je ne peux pas changer. Il existait avant IRunnable; Je ne peux pas faire il implémenter mon interface. Mais je veux l'utiliser comme si il implémente IRunnable - sans doute parce qu'il a une méthode Run, ou quelque chose comme ça. En d'autres termes, je veux être en mesure d'avoir du code qui attend un IRunnable et fonctionnera avec un Cheetah. OK, donc je pourrais toujours écrire un accord CheetahWrapper. Mais humour moi et laissez-moi écrire quelque chose d'un peu plus souple - que diriez-vous d'un RunnableAdapter?

J'envisage la définition de classe comme quelque chose comme ceci:

public class RunnableAdapter : IRunnable { 
    public delegate void RunMethod(); 

    private RunMethod Runner { get; set; } 

    public RunnableAdapter(RunMethod runner) { 
     this.Runner = runner; 
    } 

    public void Run() { 
     Runner.Invoke(); 
    } 
} 

assez simple, non? Donc, avec cela, je devrais être en mesure de faire un appel comme celui-ci:

Cheetah c = new Cheetah(); 
RunnableAdapter ra = new RunnableAdapter(c.Run); 

Et maintenant, le tour est joué: J'ai un objet qui implémente IRunner et est, dans son coeur de coeurs, un Cheetah.

Ma question est: si ce Cheetah tombe hors de la portée à un moment donné, et arrive au point où il devrait normalement être ramassé ... est-ce? Ou cette propriété RunnableAdapter de l'objet Runner constitue-t-elle une référence à l'original Cheetah, de sorte qu'elle ne sera pas collectée? Je veux certainement que cette référence reste valide, donc je me demande si la définition de classe ci-dessus est suffisante ou s'il est nécessaire de maintenir une référence à l'objet sous-jacent (par exemple via une propriété privée UnderlyingObject), juste pour empêcher le garbage collection .

+0

Cette langue est-elle C#? – Grumdrig

+0

Wow, assez ridicule j'ai oublié de mettre ces étiquettes ... oui, corrigé. –

Répondre

7

Oui, cette référence reste valide et peut en fait être récupérée en utilisant la propriété Delegate.Target - dans votre code, ra.Runner.Target.

1

Sinon, cela ressemble à un garbage collector cassé.

1

Oui, le délégué compte comme référence. Votre objet ne sera pas collecté avant que le délégué ne soit également inaccessible.