Gro*_*ozz 4 c# linq dictionary
请考虑以下代码:
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;
});
}
Run Code Online (Sandbox Code Playgroud)
我正在谈论闭包中的trader变量的初始化,它在实例化的同一行中使用它自己.
我最近一直在使用这种处理字典的模式,因为我真的不喜欢未初始化的变量:)并且想知道这是否有保证将来编译.
除了看起来很奇怪之外,它没有任何问题 - 技术上.
首先,trader
将执行声明,因此存在没有赋值的Trader对象.其次,TryGetValue
评估零件并返回true或false.如果返回true,则返回现在分配的trader
内容.如果返回false,则创建新的Trader并通过赋值操作将其添加到字典中.赋值操作的结果是分配给的对象的值.那是新的交易员.第三,将返回三元运算符的结果并将其分配给trader
.
这种情况不太可能在未来发生变化,因为改变这样一个声明的评估顺序是一个非常突破性的变化.
更新:
因为它看起来很奇怪,我不会用它.我会通过为IDictionary<TKey, TValue>
被调用创建一个扩展方法来解决这个问题GetOrAdd
.
它可能看起来像这样:
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;
}
Run Code Online (Sandbox Code Playgroud)
你会这样称呼它:
var trader = traderSet.GetOrAdd(key, k => new Trader(s.gateway, s.broker));
Run Code Online (Sandbox Code Playgroud)
这是一个更清洁,它甚至比你奇怪的方法更短.
顺便说一句:你可以用它ConcurrentDictionary<TKey, TValue>
代替.这个类已经有了一个方法,GetOrAdd
并且具有线程安全的好处.
归档时间: |
|
查看次数: |
230 次 |
最近记录: |