我想创建一个列表,其中每个元素必须有3个字段:KeyType,KeyName,Value。 Value
字段的类型应为:String,Cardinal,Integer,Byte,Boolean ...取决于KeyType
的值。我需要这个来制作像windows注册表这样的东西。有可能吗?
答案 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
然后你只需要确定有效载荷的类型。使用变体类型,例如TValue
或Variant
,尽管后者会限制您使用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>
,您就完成了。
在我看来,为了保持一致性,在这里使用通用容器很重要。这样做可以让您将容器和元素的各个方面分开。