TDictionary...
TDictionary<>...
why oh why doesn't myDict[x] := foobar; just call AddOrSet value, instead of forcing me to call Add for new values.
why oh why doesn't myDict[x] := foobar; just call AddOrSet value, instead of forcing me to call Add for new values.
IMHO because it's not very clean... but you can write your own generic dictionary based on TDictionary that has this feature.
ReplyDeleteDorin Duminica Well a matter of taste perhaps. I think it's considerably cleaner.
ReplyDeleteHowever, it's also how a dictionary works in several other languages, for example C++ and Python.
AddOrSet is a problem if you set an entry that already have been referenced elsewhere.
ReplyDeleteyeah, not so cool... but it is what it is, here's something similar but not quite:
ReplyDeletetype
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;
Lars Fosdal That sounds like a really bad idea to do anyway, or I'm misunderstanding you.
ReplyDeleteIn 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.
ReplyDeleteDorin Duminica Cheers, though if you're at that stage one might just reimplement the whole thing and avoid some other interesting design choices.
ReplyDeleteLars 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.
ReplyDeleteYou'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.
ReplyDeleteLars Fosdal TDictionary is not thread safe. The thread-safety of whatever you put into it seems orthogonal to my complaint?
ReplyDeleteIt 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.
ReplyDeleteLars Fosdal Could be, however I'd vastly prefer it being easier to use and consistent with other languages.
ReplyDeleteThe dictionary in Spring4d behaves as you expect it.
ReplyDeleteStefan Glienke Spring4D does look nice indeed. Will have to convince my coworkers to add yet another dependency though...
ReplyDeleteAsbjørn Heid -- Spring4D is well, well worth adding.
ReplyDelete