C# 中如何实现引用返回?

2024-04-28

既然 C# GC 可以移动内存,那么如何实现引用返回呢?下面的代码会导致“未定义的行为”吗?

public struct Record
{
    public int Hash;
    public VeryLargeStruct Data;
}

public class SomeClass
{
    private Record[] _records = new Record[16];
    public ref VeryLargeStruct GetDataAt(int index) =>
                    ref _records[index].Data;
}

我假设如果与 _records 引用关联的内存发生移动,它将使本地引用无效,例如:

ref var data = ref someClassInstance.GetDataAt(0);

When GetDataAt返回by-ref,其实就是所谓的托管指针正在使用中。它们可以指向内部对象 - 就像您的情况一样,数组内的装箱结构的字段。这就是为什么它们也被称为内部指针.

GC 在标记和重定位时能够正确处理它们。换句话说:

  • 在标记阶段,这样内部指针被认为是它指向的对象的根 - 因此你的_records数组不会被视为无法访问。它基本上扫描周围的内存区域以查找包含由内部指针表示的地址的对象。
  • 在重新定位阶段(如果发生),这样的内部指针已正确更新,因此在移动后它将继续指向同一对象的同一位置。

就目前的实施而言,这一切都是基于砖块和插头树机制。如果您对此感兴趣,我推荐您参考我自己的文章 http://tooslowexception.com/managed-pointers-in-net/关于它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 中如何实现引用返回? 的相关文章

随机推荐