c# - 奇怪的 C# 弱引用行为

标签 c# c#-4.0 weak-references

我花了一些时间学习弱引用在 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/

相关文章:

java - 为什么 java 类 WeakReference 不覆盖哈希码和等于

objective-c - 使用运行时将弱 ivar 添加到 Objective-C 类

c# - 在 C# 中从 XML 中删除元素

c# - 命令执行后调用事件

c#-4.0 - SignalR 组未获取数据

c# - Visual Studio 2010 : How to enforce build order of projects in a solution?

swift - Swift 中的 Compare/Equatable 弱泛型

c# - 运行 Windows 窗体应用程序的多个实例

c# - 如何在 asp.net c# 应用程序中放置一个可选的文件上传按钮?

performance - 更快的素数生成 C#