Где в FieldInfo хранится значение самого поля? C#
Недавно начал изучать рефлексию и то, что находится под капотом. Сегодня начал разбираться с "внутренностями" полей. В итоге понял, что поля - это классы, которые хранят своё имя, тип, инфу о том, что это поле, значения перечисления FieldAttributes, значения перечисления BindingFlags, FieldHandle и т. д. и т. п., но я не смог найти само значение этого поля. Где в поле, то есть в FieldInfo, находится значение самого поля?
Ответы (1 шт):
Само поле хранится в куче, внутри структуры объекта:
Class.cs
public sealed class Class
{
public int Field { get; set; }
}
Memory dump (x86) (выравнивание 4 байта)
╓───────────────────╥───────────────────╥───────────────────╖
║ Type Handle ║ Sync Block Index ║ Field (Наше поле) ║
╟────┬────┬────┬────╫────┬────┬────┬────╫────┬────┬────┬────╢
║ .. │ .. │ .. │ .. ║ .. │ .. │ .. │ .. ║ 00 │ 00 │ 00 │ 00 ║
╙────┴────┴────┴────╨────┴────┴────┴────╨────┴────┴────┴────╜
И вот эта вся канитель хранится в куче с остальными объектами.
FieldInfo на то и Info, что содержит только информацию о расположении поля, т. е. смещение (смещение отсчитывается от конца Sync Block Index), в нашем случае это 0.
И когда мы пишем вот такой код:
var @class = new Class { Field = 0x11_22_33_44 };
var field = @class.GetType().GetField("Field")!;
var fieldValue = field.GetValue(@class);
…его (последнюю строчку) можно интерпретировать (грубо) вот так:
typedef struct FieldInfo {
⋮ // прочая инфа
size_t offset;
} FieldInfo;
⋮
long fieldValue = *(long*)((char*)class + 8 + field->offset); // работает только на x86