TL;DR我很快用 C# 写了一个概念验证 XorLinkedList implementation。
在 C# 中使用 unsafe 代码是绝对可能的。不过有一些限制:
- 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 字节,所以这个指针将是您最不关心的问题;)