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;
}
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);
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:
_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.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.