简体   繁体   English

访问修改后的闭包:ReSharper

[英]Access to modified closure: ReSharper

I created a library that handles database access. 我创建了一个处理数据库访问的库。 I recently added transaction handling; 我最近添加了事务处理; however, I came across a small issue. 但是,我遇到了一个小问题。 To outline this, I wrote this sample for demonstration purposes: 为了概述这一点,我为演示目的编写了此样本:

class Program
{
    static void Main(string[] args)
    {
        String data = null;
        DoAction(ref data, () =>
        {
            Console.WriteLine(data);
        });
        Console.ReadLine();
    }

    private static void DoAction(ref String data, Action action)
    {
        if (data == null)
            data = "Initialized Data";
        action();
    }
}

I get "Access to modified closure" underline on the following code line for the 'data' variable: 我在“ data”变量的以下代码行中看到“访问修改的闭包”下划线:

Console.WriteLine(data);

I understand that the modification of the ref data variable can cause issues (eg when running foreach loops). 我知道修改ref数据变量可能会导致问题(例如,在运行foreach循环时)。 However, in the following case, I don't see this to happen. 但是,在以下情况下,我认为这种情况不会发生。

Here is another version with a loop changing the variable further - the output is as expected: 这是另一个版本,其中循环进一步更改了变量-输出符合预期:

class Program
{
    static void Main(string[] args)
    {
        String data = null;
        for (var i = 0; i < 10; i++)
            DoAction(ref data, () =>
            {
                Console.WriteLine(data);
            });
        Console.ReadLine();
    }

    private static void DoAction(ref String data, Action action)
    {
        if (data == null)
            data = "Initialized Data";
        else
            data += "|";

        action();
    }
}

ReSharper offers me to create a local variable, but I explicitly want to use the created string from the DoAction() method. ReSharper为我提供了一个创建局部变量的方法,但我明确希望使用DoAction()方法中创建的字符串。 If I would accept ReSharpers approach, it actually would break the code. 如果我接受ReSharpers方法,则实际上会破坏代码。 Is there any other way to solve this problem? 还有其他解决方法吗? I'd like to use this Action approach, but I don't want ReSharper to complain about it either (and possibly not disable ReSharpers inspection). 我想使用这种Action方法,但是我也不希望ReSharper对此抱怨(并且可能不会禁用ReSharpers检查)。

Any suggestions? 有什么建议么?

I would suggest avoid using a ref parameter for this in the first place - it seems needlessly complicated to me. 我建议首先避免为此使用ref参数-对我而言,这似乎不必要地复杂。 I'd rewrite DoAction as: 我将DoAction重写为:

static string DoAction(string data, Action<string> action)
{
    data = data == null ? "Initialized Data" : data + "|";
    action(data);
    return data;
}

Then you can have: 然后您可以拥有:

data = DoAction(data, Console.WriteLine);

or if you want to use a lambda expression: 或者,如果您想使用lambda表达式:

data = DoAction(data, txt => Console.WriteLine(txt));

You can make DoAction a void method if you don't actually need the result afterwards. 如果您以后实际上不需要结果,可以将DoAction void方法。 (It's not clear why you need the result to be returned and a delegate to execute in DoAction , but presumably that makes more sense in your wider context.) (尚不清楚为什么需要在DoAction返回结果委托执行,但这大概在更广泛的上下文中更有意义。)

In case you feel certain that the warning is not appropriate, there is the InstantHandleAttribute which is documented as: 如果您确定警告不适当,则可以将InstantHandleAttribute记录为:

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. 如果参数是可枚举的,则表示在执行该方法时将对其进行枚举。

I think is exactly what you want. 我想正是您想要的。

You can get the attribute from the JetBrains.Annotations package or alternatively as copy-paste from ReSharper options. 您可以从JetBrains.Annotations包中获取该属性,也可以从ReSharper选项中将其作为复制粘贴。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM