Alex Rivera | Logout

Adding the same Object twice to a TObjectDictionary frees the object

Asked 2011-08-02T01:33:53.197
15

Look at this code:

dic:=TObjectDictionary<Integer, TObject>.Create([doOwnsValues]);
testObject:=TObject.Create;
dic.AddOrSetValue(1,testObject);
dic.AddOrSetValue(1,testObject);

The code

  1. Creates a Dictionary that owns the contained values
  2. Adds a value
  3. Adds the same value again, using the same key

The surprising thing is that the object is freed when you add it the second time.

Is this intended behaviour? Or a bug in the Delphi libraries?

The documentation simply says "If the object is owned, when the entry is removed from the dictionary, the key and/or value is freed". So it seems a little odd to Free an object that I have just asked it to Add!

Is there any way to tell the TObjectDictionary to not do this? Currently, each time I add a value I have to check first if that Key-Value combination is already in the Dictionary.

Delphi 2010

[EDIT: After reading all the comments:

My conclusions (for what they are worth)]

  • This seems to be the intended behaviour
  • There is no way of modifying this behaviour
  • Don't use TObjectDictionary (or any of the other similar classes) for anything other than the common "Add these objects to the container. Leave them there. Do some stuff. Free the container and all the objects you added" usage. If you are doing anything more complicated, it's better to manage the objects yourself.
  • The behaviour is poorly documented and you should read the source if you want to really know what's going on

[/EDIT]

Edit
Report

1 Answer

7

Thats because with reusing the key youre replacing the object and since the dictionary owns the object it frees the old one. Dictionary doesn't compare the value, only key, so it doesn't detect that the value (object) is same. Not a bug, as designed (IOW user error).

On second thought - perhaps the designer of the dict should have taken more care to have both doOwnsValues and AddOrSetValue()... one can argue both ways... I suggest you file it in QC, but I wouldn't hold my breath - it has been so now in at least two releases so it's unlikely to change.

answered 2011-08-02T01:39:56.930

Your Answer