如何实现不同元素类型的链表?

How to implement a linked list with different element types?

我想创建一个列表,其中每个元素都必须有 3 个字段:KeyType、KeyName、Value。 Value 字段的类型应为:String、Cardinal、Integer、Byte、Boolean... 取决于 KeyType 的值。我需要它来制作类似 windows 的注册表。有可能吗?

有两种选择。

您可以使用具有变体类型的常规 record/class,例如:

type
  TDataType = (dtBoolean, dtString, ....);
  PNode = ^TNode;
  TNode = record
    Prev, Next: PNode;
    Keyname: string;
    DataType: TDataType;
    Data: variant; //or TValue
  end;

或使用变体记录

  TNode = record
    Prev, next: PNode;
    DataType: TDataType;
    Keyname: string;
    Datastring:string;
    case DataType of
      dtCardinal: (datacardinal: Cardinal);
      dtBoolean: (databoolean: boolean);
      ....
    end;

请注意,接口和字符串等托管类型不能包含在记录的变体部分中,因此您必须在此之前将它们放在普通部分中。

无法在链表中捕获注册表

请注意注册表是一棵树,您需要一棵树而不是链表,这意味着您需要 3 个链接:root, left, right.
而且您需要使用树结构。任何树都可以映射到二叉树,因此您只需要 3 个(如果您省略根节点,则为 2 个)。

TDictionary<string, TNode>

也可以。 在那种情况下,TNode 不包括 Prev/next 成员,因为字典会处理这个问题。

我会使用现成的通用链表。我确定 Spring 有一些,但是如果您不想承担所有需要的依赖项,您可以使用 Chris Rolliston 的简单链表:https://code.google.com/p/ccr-exif/source/browse/blogstuff/CCR.SimpleLinkedList.pas?r=34

然后你只需要决定负载的类型。使用变体类型,例如 TValueVariant,尽管后者会限制您使用 Windows。或者您可以制作自己的定制变体类型:

type
  TMyValue = record
    StringValue: string; // managed type must be outside variant part of record
    case DataType: TDataType of
    dtInteger:
      (IntegerValue: Integer);
    dtCardinal: 
      (CardinalValue: Cardinal);
    ....
  end;

然后你会创建一个像这样的节点类型:

type
  TNode = record
    Name: string;
    Value: TValue; // or TMyValue
  end;

最后,您的链接列表只是 TSimpleLinkedList<TNode>,您就完成了。

在我看来,为了保持一致性,在这里使用通用容器很重要。这样做可以让您将容器和元素的各个方面分开。