【问题标题】:Anonymous c# delegate within a loop循环内的匿名 C# 委托
【发布时间】:2009-11-18 16:10:51
【问题描述】:

大家好,我想写的是匿名代表。由于整数变量在委托之间共享,我需要它成为每个委托的本地实例,这样 rs[0] 总是得到 nics[0],rs[1] 总是得到 nics[1] 等等......如何我能做到吗?

for (int i = 0; i < nics.Count; i++)
   {
         rs[i] = new RollingSeries(monitor, new RollingSeries.NextValueDelegate(delegate()
         {
            return GetNetworkUtilization(nics[i]);
          }));
    }

阿卜杜勒·哈利克

【问题讨论】:

  • 非常小心你的要求。您是否希望您的第一个闭包始终在 nics[0] 中获取值在调用委托时,或者您是否希望该闭包获取恰好在 nics[0] 中的值在创建委托时?这是两件不同的事情。 nics[0] 是一个变量,因此它的值会随着时间而改变。您希望闭包看到该更改,还是忽略该更改?

标签: c# delegates


【解决方案1】:

制作i的本地副本:

   for (int i = 0; i < nics.Count; i++)
   {
         int j = i;
         rs[i] = new RollingSeries(monitor, new RollingSeries.NextValueDelegate(delegate()
         {
            return GetNetworkUtilization(nics[j]);
          }));
    }

The Beauty of Closures

【讨论】:

  • 或数组中项目的本地副本。
【解决方案2】:

每次迭代使用局部变量获取不同的值

for (int i = 0; i < nics.Count; i++)
   {
         int localI = i;
         rs[i] = new RollingSeries(monitor, new RollingSeries.NextValueDelegate(delegate()
         {
            return GetNetworkUtilization(nics[localI]);
          }));
    }

【讨论】:

    【解决方案3】:

    int j = i 放入循环中,并在 lambda 表达式中引用 j

    如果您对为什么会发生这种情况感到好奇,这里是一个包含详细技术解释的 MSDN 博客条目:Closing over the loop variable considered harmful

    【讨论】: