我通常知道“隐式捕获关闭”意味着什么,但是,今天我遇到了以下情况:
public static void Foo (Bar bar, Action<int> a, Action<int> b, int c)
{
bar.RegisterHandler(x => a(c)); // Implicitly captured closure: b
bar.RegisterHandler(x => b(c)); // Implicitly captured closure: a
}
为什么我也隐含地捕捉其他动作?如果我评论两条线中的任何一条,另一条不会给我警告。有人知道ReSharper警告我的危险吗?
编辑:ReSharper 8.0.1
答案 0 :(得分:35)
这里的问题是,当您关闭变量时,幕后发生的事情是编译器创建一个新的未命名类型,为该类型提供在该块中关闭的每个变量的实例字段,为该代码块中的每个匿名方法提供一个方法,然后传递该对象的单个实例。
这意味着第一个委托的生命周期使该闭包对象保持活动状态,除内部b
之外,它还引用了对象a
,反之亦然。
现在在你的情况下,这不是一个问题,因为Action
不是特别记忆密集的东西,所以保持它存活一段时间并不是真正的问题。
答案 1 :(得分:0)
答案 2 :(得分:0)
警告,我为此疯狂:
List<List<string>> allowed = AllowedSCACSwaps;
foreach (List<string> c in allowed.Where(c => c.Contains(scac)))
{
csc = openCycles.FirstOrDefault(icsc => (icsc.CustomerCode == customerCode) && c.Contains(icsc.SCAC));
if (null != csc)
{
return csc;
}
}
说&#34;对customerCode进行隐式关闭&#34;
string cc = customerCode.ToUpperInvariant();
string sc = scac.ToUpperInvariant(); List<List<string>> allowed = AllowedSCACSwaps;
foreach (List<string> c in allowed.Where(c => c.Contains(sc)))
{
csc = openCycles.FirstOrDefault(icsc => (icsc.CustomerCode == cc) && c.Contains(icsc.SCAC));
if (null != csc)
{
return csc;
}
}
很好。
我疯了的原因?
scac和customerCode都是传递给方法的字符串。 但即使我用cc替换customerCode,我仍然会收到相同的警告。
关闭实际上是scac,但Resharper误报了它。