2009-11-12 12 views
6

Ich hatte Schwierigkeiten, eine gute Möglichkeit zu finden, diese Frage zu formulieren, also lassen Sie mich versuchen, mit einem Beispiel zu erklären:Stellt eine Referenz auf einen Delegaten eine Referenz auf ein Objekt dar (um eine Speicherbereinigung zu verhindern)?

Angenommen, ich habe eine Schnittstelle. Der Einfachheit halber werde ich sagen, dass die Schnittstelle IRunnable ist, und es bietet eine einzige Methode, Run. (Das ist nicht real; es ist nur ein Beispiel.)

Nehmen wir jetzt an, ich habe eine bereits existierende Klasse, nennen wir sie Cheetah, die ich nicht ändern kann. Es existierte vor IRunnable; Ich kann nicht machen es meine Schnittstelle implementieren. Aber ich möchte es als verwenden, implementiert IRunnable - vermutlich, weil es eine Run Methode oder etwas ähnliches hat. Mit anderen Worten, ich möchte in der Lage sein, Code zu haben, der IRunnable erwartet und mit einem Cheetah arbeitet.

OK, so könnte ich immer eine CheetahWrapper Art von Angebot schreiben. Aber humor mich und lass mich etwas flexibler schreiben - wie wäre es mit einem RunnableAdapter?

Ich sehe die Klassendefinition als etwas wie folgt aus:

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(); 
    } 
} 

einfach genug, nicht wahr? Also mit diesem, soll ich in der Lage sein, einen Aufruf wie folgt zu machen:

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

Und jetzt, voila: Ich habe ein Objekt, das IRunner und ist in seinem Innersten implementiert, ein Cheetah.

Meine Frage ist: wenn diese Cheetah von mir irgendwann aus dem Rahmen fällt, und an den Punkt kommt, wo es normalerweise Müll gesammelt würde ... wird es? Oder stellt diese RunnableAdapter Objekt Runner Eigenschaft eine Referenz auf das Original Cheetah, so dass es nicht gesammelt werden? Ich möchte natürlich, dass diese Referenz gültig bleibt, also frage ich mich, ob die obige Klassendefinition ausreicht oder ob es notwendig wäre, einen Verweis auf das zugrundeliegende Objekt beizubehalten (etwa über eine private UnderlyingObject-Eigenschaft), nur um eine Speicherbereinigung zu verhindern .

+0

Ist diese Sprache C#? – Grumdrig

+0

Wow, ziemlich lächerlich Ich habe vergessen, diese Tags zu setzen ... ja, behoben. –

Antwort

7

Ja, diese Referenz bleibt gültig und kann mithilfe der Eigenschaft Delegate.Target abgerufen werden - in Ihrem Code wie ra.Runner.Target.

1

Wenn nicht, klingt das wie ein kaputter Müllsammler.

1

Ja, der Delegierte gilt als Referenz. Ihr Objekt wird erst dann als Garbage Collection behandelt, wenn der Delegat ebenfalls nicht erreichbar ist.

Verwandte Themen