TL;DR我很快用 C# 编写了一个概念验证的XorLinkedList 实现。
在 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;
}
结论
就个人而言,我永远不会在 C# 中使用 XorLinkedList(也许在 C 中,当我在编写内存分配器或内核数据结构等非常低级的系统内容时。在任何其他设置中,存储效率的小幅提升确实不值得痛苦。事实上,你不能将它与 C# 中的托管对象一起使用,这使得它对于日常编程几乎毫无用处。
今天,存储几乎是免费的,即使是主内存,如果你使用 C#,你可能不太关心存储。我在某处读到 CLR 对象标头大约为 40 个字节,因此这个指针将是您最不关心的问题;)