It is my understanding that after all strong references to the Target of a WeakReference are set to null and the GC is invoked, that weak reference should no longer be alive.
However, the code below does not appear to follow this expectation:
static void Main(string[] _) {
var person = new Person();
var wr = new WeakReference(person);
person = null;
// We should have access to the person here
if (wr.Target is Person shouldExist)
{
Console.WriteLine($"Person exists! IsAlive: {wr.IsAlive}.");
shouldExist = null;
}
else
{
Console.WriteLine($"Person does not exist :( IsAlive: {wr.IsAlive}.");
}
// Invoke GC.Collect.
GC.Collect();
if (wr.Target is Person shouldNotExist)
{
Console.WriteLine("This person should have been garbage collected");
Console.WriteLine($"IsAlive: {wr.IsAlive}");
}
else
{
Console.WriteLine("This person was garbage collected and weak reference is no longer alive");
Console.WriteLine($"IsAlive: {wr.IsAlive}");
}
}
where
class Person
{
private int mI = 3;
public int MI { get => mI; set => mI = value; }
}
And the output is
Person exists! IsAlive: True. This person should have been garbage collected IsAlive: True
I was expecting the output to be:
Person exists! IsAlive: True. This person was garbage collected and weak reference is no longer alive IsAlive: False
Am I missing something here about how weak references work?
The use of the references to the
Personobject inMain()is keeping the object alive until the end of the method.If you change the code as follows (so that the access to the
Personobject is in a separate method), it will work as expected in C# 12/.NET 8:NOTE: This behaviour is not guaranteed and may vary in different versions of C#/.NET.