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

时间:2015-05-12 16:11:53

标签: list delphi types delphi-2009

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

2 个答案:

答案 0 :(得分:1)

有两种选择。

您可以使用具有变体类型的nornal记录/类,例如:

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不包括上一个/下一个成员,因为字典会处理这个问题。

答案 1 :(得分:1)

我会使用现成的通用链表。我确信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>,您就完成了。

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