TL; DR Я быстро написал подтверждение концепции Реализация XorLinkedList в C #.
Это абсолютно возможно, используя небезопасный код в C #. Однако есть несколько ограничений:
- XorLinkedList должен быть "неуправляемой структурой", т. Е. Они не могут содержать управляемые ссылки
- Из-за ограничения в обобщениях C # связанный список не может быть универсальным (даже с
where T : struct
)
Последнее, похоже, связано с тем, что вы не можете ограничить универсальный параметр неуправляемыми структурами . С помощью where T : struct
вы также можете разрешить структуры, содержащие управляемые ссылки.
Это означает, что ваш XorLinkedList может содержать только примитивные значения, такие как целые, указатели или другие неуправляемые структуры.
Низкоуровневое программирование на C #
private static Node* _ptrXor(Node* a, Node* b)
{
return (Node*)((ulong)a ^ (ulong)b);//very fragile
}
Очень хрупкий, я знаю. Указатели C # и IntPtr не поддерживают XOR-оператор (вероятно, хорошая идея).
private static Node* _allocate(Node* link, int value = 0)
{
var node = (Node*) Marshal.AllocHGlobal(sizeof (Node));
node->xorLink = link;
node->value = value;
return node;
}
Не забудьте потом Marshal.FreeHGlobal
эти узлы (Реализуйте полный шаблон IDisposable и убедитесь, что бесплатные вызовы размещены за пределами блока if(disposing)
.
private static Node* _insertMiddle(Node* first, Node* second, int value)
{
var node = _allocate(_ptrXor(first, second), value);
var prev = _prev(first, second);
first->xorLink = _ptrXor(prev, node);
var next = _next(first, second);
second->xorLink = _ptrXor(node, next);
return node;
}
Заключение
Лично я никогда не использовал бы XorLinkedList в C # (возможно, в C, когда я пишу действительно низкоуровневые системные вещи, такие как распределители памяти или структуры данных ядра. В любом другом случае небольшой выигрыш в эффективности хранения действительно не стоит боль. Тот факт, что вы не можете использовать его вместе с управляемыми объектами в C #, делает его практически бесполезным для повседневного программирования.
Кроме того, сегодня хранилище почти свободно, даже основная память, и если вы используете C #, вы, вероятно, не слишком заботитесь о хранилище. Я где-то читал, что заголовки объекта CLR были около 40 байтов, так что этот указатель будет наименьшим из ваших опасений;)