C# 您能否在自己的初始化行中使用变量(字典中的tryGetorels)?
考虑以下代码:C# 您能否在自己的初始化行中使用变量(字典中的tryGetorels)?,c#,linq,dictionary,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 =
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;
});
}
private Dictionary createTradersFor(IEnumerable设置)
{
var traderSet=新字典();
返回设置。ToDictionary(s=>s,s=>
{
var key=Tuple.Create(s.gateway,s.broker);
Trader Trader=traderSet.TryGetValue(输入,输出Trader)
交易者
:traderSet[key]=新交易者(s.gateway,s.broker);
回报交易者;
});
}
我特别讨论的是在闭包中初始化trader变量,它在实例化的同一行中使用自身
我最近经常使用这种处理字典的模式,因为我真的不喜欢未初始化的变量:),我想知道这是否保证在将来编译。保证是一个强有力的词,但它非常非常,将来它不太可能停止编译-语言团队努力保持向后兼容性,除非出现巨大的范式转换(即从VB6到第一个VB.NET),否则该代码应该继续构建良好 事实上,我认为这是一个很好的技巧,但我花了一些时间才看到TryGetValue被用于三元操作(其他人也有同样的问题),因此您可能在这里保存了一行代码(将交易员声明移动一行),但您以后可能需要支付额外的维护成本(或继承此代码的人),所以也许你应该重新考虑分开声明
Trader trader;
trader = traderSet.TryGetValue(key, out trader) ?
...
除了看起来很奇怪之外,从技术上讲,它没有什么问题。
首先,将执行
trader
的声明,因此存在一个没有赋值的trader对象。
其次,计算TryGetValue
部分并返回true或false。如果返回true,则将返回现在分配的交易员
。如果返回false,则创建一个新的交易者,并通过赋值操作将其添加到字典中。指定操作的结果是指定给的对象的值。这就是新的交易者。
第三,三元运算符的结果将被返回并分配给交易员
这不太可能在将来改变,因为改变这样一个语句的求值顺序是一个非常突破性的改变
更新:因为它看起来很奇怪,我不会用它。我将通过为
IDictionary
创建一个名为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;
}
这是非常干净的而且比你的奇形怪状的方法还要短
顺便说一句:你可以用这个来代替。这个类已经有了一个方法GetOrAdd
,并且具有线程安全的优点
Trader trader = traderSet.TryGetValue(key, out trader)
? trader
: traderSet[key] = new Trader(s.gateway, s.broker);
vs
我也看不出您所做的有任何错误,尽管我不确定它是否比直接的替代方案更好,这种替代方案不需要未来的程序员来计算代码的功能。这是现在编译的吗?TryGetValue返回布尔值,交易者类型为trader。对我来说,这看起来像是类型不匹配。这是可以编译的,因为完整的三元运算符的结果被分配给
trader
。三元运算符的结果无疑是Trader
类型。唯一的缺点是,由于Trader
变量尚未声明,因此您无法在该行获得intellisense。这有点让人困惑,是扩展方法的好主意
Trader trader = traderSet.TryGetValue(key, out trader)
? trader
: traderSet[key] = new Trader(s.gateway, s.broker);
Trader trader;
if (!traderSet.TryGetValue(key, out trader)) {
trader = traderSet[key] = new Trader(s.gateway, s.broker);
}