Does a reference to a delegate constitute a reference to an object (to prevent garbage collection)?
I had trouble coming up with a good way to word this question, so let me try to explain by example:
Suppose I have some interface. For simplicity's sake, I'll say the interface is IRunnable
, and it provides a single method, Run
. (This is not real; it's only an example.)
Now, suppose I have some pre-existing class, let's call it Cheetah
, that I can't change. It existed before IRunnable
; I can't make it implement my interface. But I want to use it as if it implements IRunnable
--presumably because it has a Run
method, or something like it. In other words, I want to be able to have code that expects an IRunnable
and will work with a Cheetah
.
OK, so I could always write a CheetahWrapper
sort of deal. But humor me and let me write something a little more flexible--how about a RunnableAdapter
?
I envision the class definition as something like this:
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();
}
}
Straightforward enough, right? So with this, I should be able to make a call like this:
Cheetah c = new Cheetah();
RunnableAdapter ra = new RunnableAdapter(c.Run);
And now, voila: I have an object that implements IRunner
and is, in its heart of hearts, a Cheetah
.
My question is: if this Cheetah
of mine falls out of scope at some point, and gets to the point where it would normally be garbage collected... will it? Or does this RunnableAdapter
object's Runner
property constitute a reference to the original Cheetah
, so that it won't be collected? I certainly want that reference to stay valid, so basically I'm wondering if the above class definition is enough or if it would be necessary to maintain a reference to the underlying object (like via some private U开发者_运维百科nderlyingObject
property), just to prevent garbage collection.
Yes, that reference remains valid, and can in fact be retrieved using the Delegate.Target property -- in your code, as ra.Runner.Target
.
As others said it counts as a reference. You might find this story interesting. http://asserttrue.blogspot.com/2008/11/garbage-collection-causes-car-crash.html
If not, that sounds like a broken garbage collector.
Yes, the delegate counts as a reference. Your object will not be garbage collected until the delegate is also unreachable.
精彩评论