19

The Delphi XE2 online help (as well as the Embarcadero DocWiki) is very thin on the documentation of TObjectDictionary (or I am too stupid to find it).

As far as I understand it, it can be used to store object instances that can be accessed via string keys (basically what was always possible with a sorted TStringList but typesafe). But I am at a loss on how to actually declare and use it.

Any pointers?

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
dummzeuch
  • 10,975
  • 4
  • 51
  • 158
  • The keys in a TDictionary or TObjectDictionary do not have to be strings. They can be any type. The *values* in a TObjectDictionary must extend TObject, whereas TDictionary can store values of any type. – awmross Dec 12 '11 at 04:25

1 Answers1

31

The main difference between a TObjectDictionary and a TDictionary is that provides an mechanism to specify the Ownership of the keys and/or values added to the collection (dictionary), So you don't need to worry about freeing these objects.

Check this basic sample

{$APPTYPE CONSOLE}    
{$R *.res}
uses
  Generics.Collections,
  Classes,
  System.SysUtils;


Var
  MyDict  : TObjectDictionary<String, TStringList>;
  Sl      : TStringList;
begin
  ReportMemoryLeaksOnShutdown:=True;
  try
   //here i'm  creating a TObjectDictionary with the Ownership of the Values 
   //because in this case the values are TStringList
   MyDict := TObjectDictionary<String, TStringList>.Create([doOwnsValues]);
   try
     //create an instance of the object to add
     Sl:=TStringList.Create;
     //fill some foo data
     Sl.Add('Foo 1');
     Sl.Add('Foo 2');
     Sl.Add('Foo 3');
     //Add to dictionary
     MyDict.Add('1',Sl);

     //add another stringlist on the fly 
     MyDict.Add('2',TStringList.Create);
     //get an instance  to the created TStringList
     //and fill some data
     MyDict.Items['2'].Add('Line 1');
     MyDict.Items['2'].Add('Line 2');
     MyDict.Items['2'].Add('Line 3');


     //finally show the stored data
     Writeln(MyDict.Items['1'].Text);
     Writeln(MyDict.Items['2'].Text);        
   finally
     //only must free the dictionary and don't need to worry for free the TStringList  assignated to the dictionary
     MyDict.Free;
   end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

Check this link Generics Collections TDictionary (Delphi) for a complete sample about how to use a TDictionary (remember the only difference with the TObjectDictionary is the Ownership of the keys and/or values that is specified in the constructor, So the same concepts applies to both)

dummzeuch
  • 10,975
  • 4
  • 51
  • 158
RRUZ
  • 134,889
  • 20
  • 356
  • 483
  • 8
    +1 Use `doOwnsKeys` if you want similar treatment for the keys – David Heffernan Dec 11 '11 at 19:12
  • 1
    The `StringLis`t object `S1` will only be freed if this is a Non-ARC application. But if your application is using Automatic Reference Counting the `StringList` object will not be destroyed after removing it from dictionary due the fact that your varible S1 is still referencing it. So the object Will get destroyed only after the variable S1 gets out of scope which in this example is on Application termination since `S1` is declared as global variable. – SilverWarior Aug 28 '19 at 08:59