9 Stimmen

Stellt ein Verweis auf einen Delegaten einen Verweis auf ein Objekt dar (um Garbage Collection zu verhindern)?

Ich hatte Schwierigkeiten, diese Frage gut zu formulieren, also möchte ich versuchen, sie anhand eines Beispiels zu erklären:

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

Nehmen wir nun an, ich habe eine bereits vorhandene Klasse, nennen wir sie Cheetah die ich nicht ändern kann. Es existierte schon vorher IRunnable ; ich kann nicht machen. es implementiert meine Schnittstelle. Aber ich möchte es verwenden als ob es implementiert IRunnable -Vermutlich, weil es einen Run Methode oder etwas Ähnlichem. Mit anderen Worten, ich möchte in der Lage sein, Code zu haben, der eine IRunnable und arbeitet mit einer Cheetah .

OK, ich könnte also jederzeit ein CheetahWrapper eine Art Deal. Aber lassen Sie mich etwas Flexibleres schreiben - wie wäre es mit einem RunnableAdapter ?

Ich stelle mir die Klassendefinition in etwa so vor:

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

Das ist doch ganz einfach, oder? Damit sollte ich also in der Lage sein, einen Anruf wie diesen zu tätigen:

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

Und jetzt, voilà: Ich habe ein Objekt, das Folgendes implementiert IRunner und ist im Grunde seines Herzens ein Cheetah .

Meine Frage ist: Wenn diese Cheetah von mir irgendwann aus dem Geltungsbereich herausfällt und an den Punkt gelangt, an dem es normalerweise garbage collected werden würde... wird es das? Oder wird dies RunnableAdapter das Objekt Runner Eigenschaft einen Verweis auf das Original Cheetah damit sie nicht eingesammelt werden? Ich möchte auf jeden Fall, dass dieser Verweis gültig bleibt, also frage ich mich, ob die obige Klassendefinition ausreicht oder ob es notwendig wäre, einen Verweis auf das zugrunde liegende Objekt zu pflegen (z. B. über eine private UnderlyingObject Eigenschaft), nur um die Garbage Collection zu verhindern.

0 Stimmen

Wow, ziemlich lächerlich, dass ich vergessen habe, diese Tags zu setzen... ja, korrigiert.

10voto

itowlson Punkte 72130

Ja, dieser Verweis bleibt gültig und kann in der Tat mit der Eigenschaft Delegate.Target abgerufen werden - in Ihrem Code, als ra.Runner.Target .

4voto

Wie andere bereits sagten, gilt sie als Referenz. Diese Geschichte könnte für Sie interessant sein. http://asserttrue.blogspot.com/2008/11/garbage-collection-causes-car-crash.html

0 Stimmen

Wow, das ist... verdammt eindeutig.

2voto

Grumdrig Punkte 15728

Wenn nicht, klingt das nach einem defekten Garbage Collector.

2voto

Justin Grant Punkte 42760

Ja, der Delegat zählt als Referenz. Ihr Objekt wird erst dann gelöscht, wenn der Delegat ebenfalls unerreichbar ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X