在我看来,当我在WeakReference
对象类的委托方法上使用该类时,对象类被 GC 收集,但它的另一个副本仍然存在于WeakReference
?
我觉得很难用语言来解释。我举个例子。我有以下名为的对象类TestObject
:
class TestObject
{
public string message = "";
private delegate string deleg();
public TestObject(string msg)
{
message = msg;
}
public Delegate GetMethod()
{
deleg tmp = this.TestMethod;
return tmp;
}
public string TestMethod()
{
return message;
}
}
TestMethod
现在,在我的主应用程序中,我尝试TestObject
通过WeakReference
. 目的是TestObject
当所有硬引用都消失时,GC 可以收集它们。这是我的主要应用程序的样子:
static void Main(string[] args)
{
var list = new List<WeakReference>();
var obj = new TestObject("Hello 1");
list.Add(new WeakReference(obj.GetMethod()));
Console.WriteLine("Initial obj: " + ((Delegate)list[0].Target).DynamicInvoke()); //Works fine
obj = null; //Now, obj is set to null, the TestObject("Hello 1") can be collected by GC
GC.Collect(); //Force GC
Console.WriteLine("Is obj null: " + ((obj) == null ? "True" : "False"));
Console.WriteLine("After GC collection: " + ((Delegate)list[0].Target).DynamicInvoke());
Console.ReadKey();
}
这是我运行上述代码时的输出:
这是奇怪的事情。在第一行,obj
可以打印"Hello 1"
,因为它刚刚初始化并且obj
持有对TestObject
. 全部正确。接下来,obj
被设置为null
withobj = null
并且 GC 被强制收集。因此,在输出的第二行中,obj
为true
空。最后在最后一行,由于 GC 已经收集了obj
它,我希望它要么抛出 aNullReferenceException
要么在输出上不打印任何内容。但是,它实际上打印了与输出的第一行相同的内容!此时不应该TestObject
由GC收集吗?!
这引出了一个问题,如果在我将 obj 设置为 null 之后,GC 后来是否收集了TestObject
最初保存的。obj
如果我将整个对象传递给WeakReference
,即 ,new WeakReference(obj)
而不是将委托传递给WeakReference
,它会完美地工作。
不幸的是,在我的代码中,我需要传递WeakReference
给委托人。如何WeakReference
让 GC 正常工作,以便 GC 仅通过引用委托来收集对象?