如何在C#中实现按引用返回? [英] How is return by reference implemented in C#?

查看:169
本文介绍了如何在C#中实现按引用返回?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于C#GC可以移动内存,那么如何实现ref-return呢?下面的代码会导致未定义的行为吗?

Given that C# GC can move memory around, how could ref-return even be implemented? Would the code below cause 'undefined behaviour'?

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引用关联的内存移动了,它将使本地无效引用,例如:

I would assume that if memory associated with _records reference moved that it would invalidate local references such as:

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


推荐答案

GetDataAt 返回by-ref,实际上,正在使用所谓的托管指针。它们可以指向对象内部-在您的情况下,就像数组中的框式结构字段一样。这就是为什么它们也称为内部指针的原因。

When GetDataAt returns by-ref, in fact, so-called managed pointer is being used. They can point inside objects - like a field of boxed struct inside an array, in your case. That's why they are also called interior pointers.

GC可以在标记和重新放置时正确处理它们。换句话说:

GC is able to handle them properly while marking and relocating. In other words:


  • 在标记阶段,这样的内部指针被识别为对象的根指向-因此,您的 _records 数组不会被视为不可访问。它基本上会扫描周围的内存区域,以找到一个包含内部指针表示的地址的对象。

  • 在Relocate阶段(如果发生),例如内部指针已正确更新,因此移动后它将继续指向同一对象的相同位置。

  • during Mark phase, such an interior pointer is recognized as a root of the object it points into - thus your _records array won't be treated as unreachable. It basically scans the surrounding memory region to find an object that contains address represented by an interior pointer.
  • during Relocate phase (if it happens), such an interior pointer is updated properly so it will continue to point into the same place of the same object after moving it.

在当前的实现中,所有这些都是基于砖块和插件树机制。如果您对此感兴趣,请参考我自己的文章

As a matter of the current implementation, all this is based on bricks and plug trees mechanism. If you are interested in it, I refer you to my own article about it.

这篇关于如何在C#中实现按引用返回?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆