[英]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.