c# - 在直接调用委托(delegate)的情况下如何缓解 "Access to modified closure"

标签 c# closures resharper

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

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

delegate void Consume();

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

public int Hello()
{
    int a = 0;

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

    a = 1;

    return a;
}

这里没有问题,因为 ConsumeConsume 总是立即调用该函数。有没有办法解决?有什么方法可以注释函数 ConsumeConsume 以指示将立即调用委托(delegate)的 ReSharper?

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

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

做同样的事情,没有产生警告。这只是 ReSharper 的内置异常,还是我可以做类似的事情来指示立即调用委托(delegate)?

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

最佳答案

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

InstantHandle 属性标记传入的委托(delegate)。

private void ConsumeConsume([InstantHandle] Consume c)
{
    c();
}

来自InstantHandle的描述:

Tells code analysis engine if the parameter is completely handled when the invoked method is on stack. If the parameter is a delegate, indicates that delegate is executed while the method is executed. If the parameter is an enumerable, indicates that it is enumerated while the method is executed.

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

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

namespace JetBrains.Annotations
{
    [AttributeUsage(AttributeTargets.Parameter)]
    public class InstantHandleAttribute : Attribute { }
}

关于c# - 在直接调用委托(delegate)的情况下如何缓解 "Access to modified closure",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54000314/

相关文章:

visual-studio - resharper + VS Black 主题使 Note : and TODO: Blue and hard to read

c# - 使用 XmlDocument C# 在 xml 中添加根元素

c# - 检查目录是否存在动态路径

c# - 防止 Task.ContinueWith 发生异常

swift - 为什么 DispatchSemaphore.wait() 会阻止这个完成处理程序?

closures - 每个函数都是闭包吗?

linq - 我如何 LINQify 这个?

C# Bloomberg : How to loop through an array, 创建仪器对象,并添加到仪器类

javascript - 用 jquery 理解 javascript 闭包

visual-studio - Visual Studio 2017 在调试时挂起?