5

I want to use the a TDictionary in a Delphi project. But I've a problem,how i can Create a constant array of TDictionary by default value ?

For example i want to allocate 4 item for a dictionary such as bellow code (for constant array of TItem) :

...
type
  TItem = record
    _Key: string;
    _Value: string;
  end;
var
  Dic: array [0..3]of TItem=(
  (_Key:'A' ; _Value:'Apple'),
  (_Key:'B' ; _Value:'Book'),
  (_Key:'C' ; _Value:'C++'),
  (_Key:'D' ; _Value:'Delphi')
  );
...

Is there any way to do this work with TDictionary ? I want to create a constant array of Dic (but) such as bellow structure .

  ...
    var
      Dic: TDictionary<string, string>;
    begin
      Dic := TDictionary<string, string>.Create;
      try
        Dic.Add('A', 'Apple');
        Dic.Add('B', 'Book');
        Dic.Add('C', 'C++');
        Dic.Add('D', 'Delphi');
      finally
         ///
      end;
    ...

Anyone have any advice for me? (Excuse me if my English is poor !)

Behrooz
  • 684
  • 1
  • 9
  • 19

2 Answers2

11

You cannot write a constant expression that is an instance of a class.

Yet, since your TDictionary is a collection of String which is a type that you can create constants with, you could just build your TDictionary at run time from your constants. You could use records as in your question, but I like arrays:

{$IFDEF WHATEVER}
type
  TDictConstant = array[0..3, 0..1] of String;
const
  DICT_CONSTANT: TDictConstant = (('A', 'Apple'), ('B', 'Book'), ('C', 'C++'), ('D', 'Delphi'));
{$ELSE}
// If you want it "blank" for one config
type
  TDictConstant = array[0..0, 0..1] of String;
const
  DICT_CONSTANT: TDictConstant = (('', ''));
{$ENDIF}
var
  Dic: TDictionary<string, string>;

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  Dic := TDictionary<string, string>.Create;
  for i := 0 to High(DICT_CONSTANT) do
  begin
    // Ignore the "blank" ones
    if (DICT_CONSTANT[i][0] <> '') or (DICT_CONSTANT[i][1] <> '') then
    begin
      Dic.Add(DICT_CONSTANT[i][0], DICT_CONSTANT[i][1]);
    end;
  end;
end;

I've done similar in the past.

Marcus Adams
  • 53,009
  • 9
  • 91
  • 143
  • If this is going to be the accepted answer, it should answer the question that was asked. A little edit can put that right. – David Heffernan Oct 29 '13 at 19:57
  • 1
    Also, could you explain how this is better than the code in the question. It adds extra verbiage for what appears to be no discernible gain. Would you use this code rather than that in the question? – David Heffernan Oct 29 '13 at 20:01
  • @DavidHeffernan, Thanks for the comments. I updated my answer from yours. Since you already provided the explanation, I was just providing a solution. Your answer was originally chosen, but the OP switched to mine. – Marcus Adams Oct 29 '13 at 20:14
  • That's fine. It's up to the asker. But better if accepted answer does cover crux of question. Thanks for the update. – David Heffernan Oct 29 '13 at 20:18
  • I would prefer `for value in array` loop here rather than `for integer from magic-index to function(some-array)`. Just to keep it less fragile. – Arioch 'The Oct 31 '13 at 07:42
5

You cannot write a constant expression that is an instance of a class. So what you are attempting to do is not possible.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490