c# - Can you use variables in their own initialization line (tryGetOrElse in a dictionary)? -
consider 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 initialization of trader variable in closure, uses in same line being instantiated.
i've been using pattern of dealing dictionaries lot lately, cause don't uninitialized variables :) , know if guaranteed compile in future.
beside looking odd, there nothing wrong - technically.
first, declaration of trader
executed, there exists trader object without value assigned. second, trygetvalue
part evaluated , returns either true or false. if returned true, assigned trader
returned. if returns false, new trader created , added dictionary via assignment operation. result of assignment operation value of object assigned to. new trader. third, result of ternary operator returned , assigned trader
.
it unlikely change in future, because changing order of evaluation of statement breaking change.
update:
because looks odd, not use it. solve problem creating extension method idictionary<tkey, tvalue>
called getoradd
.
so:
public static tvalue getoradd<tkey, tvalue>(this idictionary<tkey, tvalue> dict, tkey key, func<tkey, tvalue> creator) { tvalue value; if(!dict.trygetvalue(key, out value)) { value = creator(key); dict.add(key, value); } return value; }
you call this:
var trader = traderset.getoradd(key, k => new trader(s.gateway, s.broker));
this a lot cleaner , shorter odd looking approach.
btw: use concurrentdictionary<tkey, tvalue>
instead. class has method getoradd
, has benefit of being thread safe.
Comments
Post a Comment