我花了一些时间学习弱引用在 C# 中的工作原理,我遇到了这种奇怪的行为。
在下面的示例代码中,第一个测试通过,第二个测试失败。似乎您无法在构造之后但在创建对它的弱引用之前修改对象的实例,而不会停止以预期方式工作的弱引用。
private class Simple
{
public Simple() { X = "Hello"; }
public string X { get; set; }
}
[Test]
public void CreatingWeakReferenceBeforeModifying()
{
var a = new Simple();
var aRef = new WeakReference(a);
a.X = "World"; // First modification to a after creating reference
a = null;
GC.Collect();
Assert.That(aRef.IsAlive, Is.False); // This assertion passes
}
[Test]
public void CreatingWeakReferenceAfterModifying()
{
var b = new Simple {X = "World"}; // First mod to b before creating ref
var bRef = new WeakReference(b);
b = null;
GC.Collect();
Assert.That(bRef.IsAlive, Is.False); // This assertion fails
}
我是不是漏掉了什么?
最佳答案
我怀疑您只会在某些情况下看到它 - 它特别有可能在调试构建下,尤其是在调试器下。
这个声明:
var b = new Simple {X = "World"};
是有效的:
var tmp = new Simple();
tmp.X = "World";
var b = tmp;
因此,即使您将 b
设置为 null,堆栈中仍然有一个局部变量引用了该对象。
在优化场景中运行时,我希望 GC 注意到局部变量将永远不会再次被读取,并将其作为 GC 根忽略 - 但可能是你的方式运行它不会让 GC 如此激进。
关于c# - 奇怪的 C# 弱引用行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13415557/