c# - C#中如何实现引用返回?
问题描述
鉴于 C# GC 可以移动内存,那么如何实现 ref-return 呢?下面的代码会导致“未定义的行为”吗?
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
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 is able to handle them properly while marking and relocating. In other words:
- 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.
推荐阅读
- ios - 将 UIScrollView 委托和 UICollectionView 委托分配给同一个类
- html - 如何撤消布尔玛嵌套元素中的is_mobile?
- c++ - 在 ns3 中使用 waf 运行时,对 `boost::random::random_device::random_device()' 的错误未定义引用
- python - 如何修复“字符串索引必须是整数”
- c# - Vuforia Cloud Reco 图像目标
- ios - ReactJs PWA 未在 iOS 上更新
- javascript - 如何让插件从 js 文件中获取代码?
- python - 如果用户输入有效,则继续运行代码
- json - Java 8 的简单 JSON 值解析
- python - Flask 不断在函数中加载可选变量