Я хочу создать список, в котором каждый элемент должен иметь 3 поля: KeyType, KeyName, Value. Тип поля Value
должен быть: String, Cardinal, Integer, Byte, Boolean ... в зависимости от значения KeyType
. Мне нужно это, чтобы сделать что-то вроде реестра Windows. Возможно ?Как реализовать связанный список с разными типами элементов?
ответ
Я бы использовал связанный список с полками. Я уверен, что у Spring есть что-то, но если вы не хотите брать на себя все зависимости, которые могли бы повлечь за собой использование простого связанного списка Криса Роллистона: 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>
и вы сделали.
На мой взгляд, важно использовать общий контейнер здесь для согласованности. Это позволяет вам разделить аспекты контейнера и элемента.
Вы не можете использовать строку в записи варианта. Компилятор там не разрешает управляемые типы. – Johan
@Johan Спасибо –
Возможны два варианта.
Вы можете использовать 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 - это все, что вам нужно (два, если вы не используете корневой узел).
TDictionary<string, TNode>
Будет также работать. В этом случае TNode не включает Prev/next members, потому что словарь позаботится об этом.
Я думаю, что ссылка на реестр была меньше о древовидной структуре и больше о возможности хранения типов вариантов. –
Используйте тип варианта. Например, «TValue». –
TDictionary возможно. –
Если вам нужен организованный деревьями контейнер - это, как мне, самая большая удача библиотеки Delphi. Другими способами существует два решения: 'массив TDataType' для доступа, связанного с индексами, и' TStringList.AddObject' для доступа, связанного с ключами. Существуют также 'THashadStringList',' TDictionary' и т. Д. Просто определите свою цель. – Abelisto