Consider the following code:
private Dictionary<RobotSettings, Trader> createTradersFor(IEnumerable<RobotSettings> settings)
{
var traderSet = new Dictionary<Tuple<IGateway, IBroker>, Trader>();
return settings.ToDictionary(s => s, s =>
{
var key = Tuple.Create(s.gateway, s.broker);
Trader trader = traderSet.TryGetValue(key, out trader)
? trader
: traderSet[key] = new Trader(s.gateway, s.broker);
return trader;
});
}
I’m talking specifically about the initialization of trader variable in a closure, which uses itself in the same line it is being instantiated.
I’ve been using that pattern of dealing with dictionaries a lot lately, cause I really don’t like uninitialized variables 🙂 and would like to know if this is even guaranteed to compile in the future.
Beside from looking very odd, there is nothing wrong with it – technically.
First, the declaration of
traderwill be executed, so there exists a Trader object without a value assigned.Second, the
TryGetValuepart is evaluated and returns either true or false. If it returned true, the now assignedtraderwill be returned. If it returns false, a new Trader is created and added to the dictionary via an assignment operation. The result of an assignment operation is the value of the object that was assigned to. That is the new trader.Third, the result of the ternary operator will be returned and assigned to
trader.It is unlikely that this will change in the future, because changing the order of evaluation of a statement like this is a very breaking change.
UPDATE:
Because it looks very odd, I would not use it. I would solve this problem by creating an extension method for
IDictionary<TKey, TValue>calledGetOrAdd.It could look like so:
You would call it like this:
This is a lot cleaner and it is even shorter than your odd looking approach.
BTW: You could use the
ConcurrentDictionary<TKey, TValue>instead. This class already has a methodGetOrAddand has the benefit of being thread safe.