Мне нравится использовать такую настройку, когда мне не нужно напрямую индексировать детей:
struct MyStruct
{
/* ... some stuff ... */
int numChilds;
IntPtr childData;
public IEnumerable<MyStruct> Children
{
get
{
int elementSize = Marshal.SizeOf(typeof(MyStruct));
for (int i = 0; i < this.numChilds; i++)
{
IntPtr data = new IntPtr(this.childData.ToInt64() + elementSize * i);
MyStruct child = (MyStruct)Marshal.PtrToStructure(data, typeof(MyStruct));
yield return child;
}
}
}
}
Если вам нужно напрямую индексировать детей, проще всего создать метод GetChild
(показан ниже). Более сложный способ - создать класс помощника / оболочки, который реализует IList<MyStruct>
. Экземпляр будет возвращен из свойства Children
, и его внутреннее будет работать, вызывая метод GetChild
. Это оставлено читателю в качестве упражнения, если оно ему понадобится.
public MyStruct GetChild(int index)
{
if (index < 0)
throw new ArgumentOutOfRangeException("index", "The index must be >= 0.");
if (index >= this.numChilds)
throw new ArgumentException("The index must be less than the number of children", "index");
int elementSize = Marshal.SizeOf(typeof(MyStruct));
IntPtr data = new IntPtr(childData.ToInt64() + elementSize * index);
MyStruct child = (MyStruct)Marshal.PtrToStructure(data, typeof(MyStruct));
return child;
}