3

如果我有以下情况:

static readonly TimeSpan ExpiredAfter = TimeSpan.FromMilliseconds(60000);

foreach (ModuleInfo info in moduleList.Where(i => DateTime.Now - i.LastPulseTime > ExpiredAfter).ToArray())
    moduleList.Remove(info);

ExpiredAfter 是否被解除或编译器是否知道它可以直接访问它?像这样写会更有效吗:

static readonly TimeSpan ExpiredAfter = TimeSpan.FromMilliseconds(60000);

static bool HasExpired(ModuleInfo i) { return DateTime.Now - i.LastPulseTime > ExpiredAfter; }

foreach (ModuleInfo info in moduleList.Where(HasExpired).ToArray())
    moduleList.Remove(info);
4

2 回答 2

1

ExpiredAfter 是否被解除或编译器是否知道它可以直接访问它?

最简单的检查方法是编译你的代码,然后在 Reflector 等中反编译。我希望编译器只生成一个直接访问静态变量的静态方法。

像这样写会更有效吗:

再一次,自己测试一下 :) 即使这样写有效,也不一定是正确的选择。哪个更适合您?这段代码对性能有多关键?它已经足够快了吗?

于 2012-07-02T17:00:06.733 回答
1

不可能捕获静态(或就此而言,任何)字段。

从语言规范:

7.15.5 外部变量范围包括 lambda 表达式或匿名方法表达式的任何局部变量、值参数或参数数组都称为匿名函数的外部变量。在类的实例函数成员中, this值被视为值参数,并且是函数成员中包含的任何匿名函数的外部变量。

7.15.5.1 捕获的外部变量当一个外部变量被匿名函数引用时,就说该外部变量已被匿名函数捕获。

静态字段绝不是局部变量、值参数或参数数组。

也就是说,我见过一些奇怪的极端情况,编译器this会无缘无故地捕获,但这似乎不是其中之一。我使用反编译器验证了在实例和静态封闭方法的情况下,C# 4.0 编译器为 lambda 生成的代码与您的“手动”版本几乎相同......除了编译器似乎是针对 lambda 情况缓存和重用对结果委托(在静态字段中)的引用。在这种情况下(通过多次执行封闭方法),这可能会违反直觉地使 lambda 方式比方法组方式更快(并增加更少的内存压力)!您必须以两种方式对其进行基准测试才能确定...

于 2012-07-02T17:28:23.870 回答