0

I want to create a list in which every element must have 3 fields: KeyType, KeyName, Value. The type of Value field should be: String, Cardinal, Integer, Byte, Boolean... depending on value of the KeyType. I need this to make something like windows registry. It is possible ?

3
  • Use a variant type. For instance TValue. Commented May 12, 2015 at 16:12
  • TDictionary<String,Variant> perhaps. Commented May 12, 2015 at 16:24
  • If you need the tree-organized container - it is, as for me, the biggest luck of the Delphi library. In the other ways there is two solutions: array of TDataType for index-related access and TStringList.AddObject for key-related access. There are also THashadStringList, TDictionary and so on. Just determine your goal. Commented May 12, 2015 at 17:37

2 Answers 2

1

I'd use an off the shelf generic linked list. I'm sure Spring has some, but if you don't want to take on all the dependencies that would entail you could use Chris Rolliston's simple linked list: https://code.google.com/p/ccr-exif/source/browse/blogstuff/CCR.SimpleLinkedList.pas?r=34

Then you just need to decide on the type of the payload. Use a variant type like, for instance, TValue or Variant, although the latter would constrain you to Windows. Or you could make your own bespoke variant type:

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;

You'd then make a node type like this:

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

Finally, your linked list is simply TSimpleLinkedList<TNode> and you are done.

In my opinion it is important to use a generic container here for the sake of consistency. Doing so allows you to keep separate the aspects of the container and the element.

Sign up to request clarification or add additional context in comments.

1 Comment

You can't use string in a variant record. The compiler does not allow managed types there.
1

There are two options.

You can use a nornal record/class with a variant type, something like:

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

Or ue a variant record

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

Note that managed types such as interfaces and strings cannot be included in the variant part of the record, so you'll have to put those in the normal part before that.

Registry cannot be captured in a linked list  

Note that the registry is a tree, you you'll need a tree instead of a linked list, that means you'll need 3 links: root, left, right.
And you'll need to use a tree structure. Any tree can be mapped to a binary tree, so 3 is all you need (two if you leave out the root node).

TDictionary<string, TNode>

Will also work. In that case TNode does not include Prev/next members because the dictionary takes care of that.

1 Comment

I think the reference to the registry was less about the tree structure, and more about the ability to hold variant types

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.