在直接调用委托的情况下如何缓解“访问修改后的闭包”

Pat*_*ick 4 c# resharper closures

我的理解是,“访问修改的闭包”警告是为了警告我从委托访问局部变量,当委托可能被存储并稍后调用或在不同的线程上调用时,局部变量实际上在以下位置不可用实际代码执行的时间。这当然是明智的。

但是,如果我正在创建一个我知道将在同一线程中立即调用的委托,该怎么办?那么就不需要警告了。例如,代码中生成警告:

delegate void Consume();

private void ConsumeConsume(Consume c)
{
    c();
}

public int Hello()
{
    int a = 0;

    ConsumeConsume(() => { a += 9; });

    a = 1;

    return a;
}
Run Code Online (Sandbox Code Playgroud)

这里不会有问题,因为ConsumeConsume总是立即调用该函数。有没有办法解决?是否有某种方法可以注释函数ConsumeConsume以指示 ReSharper 将立即调用委托?

有趣的是,当我将该ConsumeConsume(() => { a += 9; });行替换为:

new List<int>(new[] {1}).ForEach(i => { a += 9; });
Run Code Online (Sandbox Code Playgroud)

执行相同的操作,不会生成警告。这只是 ReSharper 的内置异常还是我可以做类似的事情来指示立即调用委托?

我知道我可以禁用这些警告,但这不是理想的结果。

Sza*_*zsi 5

JetBrains.Annotations使用NuGet安装包: https://www.nuget.org/packages/JetBrains.Annotations

使用该属性标记传入的委托InstantHandle

private void ConsumeConsume([InstantHandle] Consume c)
{
    c();
}
Run Code Online (Sandbox Code Playgroud)

来自InstantHandle的描述:

当调用的方法在堆栈上时,告诉代码分析引擎参数是否已完全处理。如果参数是委托,则表示在方法执行的同时执行委托。如果参数是可枚举的,则表明在执行方法时它会被枚举。

来源:https ://www.jetbrains.com/help/resharper/Reference__Code_Annotation_Attributes.html

如果您不想将整个包添加到您的项目中,那么您自己添加该属性就足够了,尽管在我看来这很hacky。

namespace JetBrains.Annotations
{
    [AttributeUsage(AttributeTargets.Parameter)]
    public class InstantHandleAttribute : Attribute { }
}
Run Code Online (Sandbox Code Playgroud)