TDictionary...

TDictionary<>...

why oh why doesn't myDict[x] := foobar; just call AddOrSet value, instead of forcing me to call Add for new values.

Comments

  1. IMHO because it's not very clean... but you can write your own generic dictionary based on TDictionary that has this feature.

    ReplyDelete
  2. Dorin Duminica Well a matter of taste perhaps. I think it's considerably cleaner.

    However, it's also how a dictionary works in several other languages, for example C++ and Python.

    ReplyDelete
  3. AddOrSet is a problem if you set an entry that already have been referenced elsewhere.

    ReplyDelete
  4. yeah, not so cool... but it is what it is, here's something similar but not quite:

    type
    TMyDic = class(TDictionary)
    protected
    ///
    /// can be overwriten later
    ///
        procedure SetValueByKey(const AKey: TKey; const ADefault, AValue: TValue); virtual;
        function GetValueByKey(const AKey: TKey; const ADefault: TValue): TValue; virtual;
    public
        property V[const Key: TKey; const ADefault: TValue]: TValue read GetValueByKey write SetValueByKey; default;
    end;

    function TMyDic.GetValueByKey(const AKey: TKey;
    const ADefault: TValue): TValue;
    begin
        if NOT Self.TryGetValue(AKey, Result) then
          Result := ADefault;
    end;

    procedure TMyDic.SetValueByKey(const AKey: TKey; const ADefault, AValue: TValue);
    begin
        Self.AddOrSetValue(AKey, AValue);
    end;

    ReplyDelete
  5. Lars Fosdal That sounds like a really bad idea to do anyway, or I'm misunderstanding you.

    ReplyDelete
  6. In a threaded app, there will always be concurrent references, Asbjørn Heid. In a single-thread app, I'd agree that it was a bad idea, unless it is done for performance.

    ReplyDelete
  7. Dorin Duminica Cheers, though if you're at that stage one might just reimplement the whole thing and avoid some other interesting design choices.

    ReplyDelete
  8. Lars Fosdal Sorry, I'm not getting it. In a multithreaded situation you'd have to protect access anyway, the current setter isn't thread-safe.

    ReplyDelete
  9. You'd have to lock both the dictionary and the object in it to make it thread safe - any use of an object in the dictionary, has to make a reference, however brief it may be - which is why an AddOrSet is dangerous.

    ReplyDelete
  10. Lars Fosdal TDictionary is not thread safe. The thread-safety of whatever you put into it seems orthogonal to my complaint?

    ReplyDelete
  11. It is, I guess, but the point of not doing the add and set by default, could very well be to ensure there is no "hidden side effects" which could be compromising if you were to attempt making it thread safe.

    ReplyDelete
  12. Lars Fosdal Could be, however I'd vastly prefer it being easier to use and consistent with other languages.

    ReplyDelete
  13. The dictionary in Spring4d behaves as you expect it.

    ReplyDelete
  14. Stefan Glienke Spring4D does look nice indeed. Will have to convince my coworkers to add yet another dependency though...

    ReplyDelete
  15. Asbjørn Heid  -- Spring4D is well, well worth adding.

    ReplyDelete

Post a Comment