2015-05-12 4 views
0

Я хочу создать список, в котором каждый элемент должен иметь 3 поля: KeyType, KeyName, Value. Тип поля Value должен быть: String, Cardinal, Integer, Byte, Boolean ... в зависимости от значения KeyType. Мне нужно это, чтобы сделать что-то вроде реестра Windows. Возможно ?Как реализовать связанный список с разными типами элементов?

+0

Используйте тип варианта. Например, «TValue». –

+0

TDictionary возможно. –

+0

Если вам нужен организованный деревьями контейнер - это, как мне, самая большая удача библиотеки Delphi. Другими способами существует два решения: 'массив TDataType' для доступа, связанного с индексами, и' TStringList.AddObject' для доступа, связанного с ключами. Существуют также 'THashadStringList',' TDictionary' и т. Д. Просто определите свою цель. – Abelisto

ответ

1

Я бы использовал связанный список с полками. Я уверен, что у 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> и вы сделали.

На мой взгляд, важно использовать общий контейнер здесь для согласованности. Это позволяет вам разделить аспекты контейнера и элемента.

+0

Вы не можете использовать строку в записи варианта. Компилятор там не разрешает управляемые типы. – Johan

+0

@Johan Спасибо –

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 - это все, что вам нужно (два, если вы не используете корневой узел).

TDictionary<string, TNode> 

Будет также работать. В этом случае TNode не включает Prev/next members, потому что словарь позаботится об этом.

+0

Я думаю, что ссылка на реестр была меньше о древовидной структуре и больше о возможности хранения типов вариантов. –

 Смежные вопросы

  • Нет связанных вопросов^_^