Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 访问修改的闭包:ReSharper_C#_C# 4.0_Resharper - Fatal编程技术网

C# 访问修改的闭包:ReSharper

C# 访问修改的闭包:ReSharper,c#,c#-4.0,resharper,C#,C# 4.0,Resharper,我创建了一个处理数据库访问的库。我最近添加了事务处理;然而,我遇到了一个小问题。为了概述这一点,我编写了这个示例用于演示: 类程序 { 静态void Main(字符串[]参数) { 字符串数据=null; DoAction(参考数据,()=> { 控制台写入线(数据); }); Console.ReadLine(); } 私有静态void DoAction(引用字符串数据、操作) { 如果(数据==null) data=“初始化数据”; 动作(); } } 我在“data”变量的以下代码行中获

我创建了一个处理数据库访问的库。我最近添加了事务处理;然而,我遇到了一个小问题。为了概述这一点,我编写了这个示例用于演示:

类程序
{
静态void Main(字符串[]参数)
{
字符串数据=null;
DoAction(参考数据,()=>
{
控制台写入线(数据);
});
Console.ReadLine();
}
私有静态void DoAction(引用字符串数据、操作)
{
如果(数据==null)
data=“初始化数据”;
动作();
}
}
我在“data”变量的以下代码行中获得“Access to modified closure”下划线:

Console.WriteLine(数据);
我知道修改ref data变量可能会导致问题(例如,在运行foreach循环时)。然而,在下面的例子中,我不认为会发生这种情况

下面是另一个版本,其中循环进一步更改变量-输出如预期所示:

类程序
{
静态void Main(字符串[]参数)
{
字符串数据=null;
对于(变量i=0;i<10;i++)
DoAction(参考数据,()=>
{
控制台写入线(数据);
});
Console.ReadLine();
}
私有静态void DoAction(引用字符串数据、操作)
{
如果(数据==null)
data=“初始化数据”;
其他的
数据+=“|”;
动作();
}
}
ReSharper让我创建一个局部变量,但我明确地希望使用从DoAction()方法创建的字符串。如果我接受ReSharpers方法,它实际上会破坏代码。还有别的办法解决这个问题吗?我想使用这种操作方法,但我也不想让ReSharper对此抱怨(可能也不想禁用ReSharper检查)


有什么建议吗?

我建议首先不要使用
ref
参数,这对我来说是不必要的复杂。我将
DoAction
重写为:

static string DoAction(string data, Action<string> action)
{
    data = data == null ? "Initialized Data" : data + "|";
    action(data);
    return data;
}
或者,如果要使用lambda表达式:

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

如果事后不需要结果,可以将
DoAction
设置为
void
方法。(不清楚为什么需要返回结果并在
DoAction
中执行委托,但在更广泛的上下文中,这可能更有意义。)

我建议首先避免使用
ref
参数,这对我来说似乎是不必要的复杂。我将
DoAction
重写为:

static string DoAction(string data, Action<string> action)
{
    data = data == null ? "Initialized Data" : data + "|";
    action(data);
    return data;
}
或者,如果要使用lambda表达式:

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

如果事后不需要结果,可以将
DoAction
设置为
void
方法。(不清楚为什么需要返回结果并在
DoAction
中执行委托,但这在更广泛的上下文中可能更有意义。)

如果您确信警告不合适,则有
InstantHandle属性
,它被记录为:

告知代码分析引擎参数是否已完全处理 当调用的方法位于堆栈上时。如果参数是委托, 指示在执行方法时执行委托。 如果参数是可枚举的,则表示已枚举该参数 在执行该方法时

我想这正是你想要的


您可以从软件包中获取属性,也可以从ReSharper选项中获取复制粘贴属性。

如果您确信警告不合适,则有
InstantHandle属性
记录为:

告知代码分析引擎参数是否已完全处理 当调用的方法位于堆栈上时。如果参数是委托, 指示在执行方法时执行委托。 如果参数是可枚举的,则表示已枚举该参数 在执行该方法时

我想这正是你想要的


您可以从包中获取属性,也可以从ReSharper选项中获取复制粘贴属性。

我还查看了:它在原始帖子注释中包含指向ReSharper文档的链接。我还查看了:它在原始帖子注释中包含指向ReSharper文档的链接。我理解-我也做了同样的事情。然而,对于Console.WriteLine(string),我有两个合适的变量。数据以及txt。这可能会让其他团队成员感到困惑。@AlexanderFuchs:这是一个有点让人困惑的方法-为什么
DoAction
负责计算一个新值并执行一个操作?如果不了解您真正想要实现的目标,就很难判断最佳解决方案是什么,但是使用
ref
参数和闭包对我来说似乎是个坏主意。对不起,在Lambda之前我不了解解决方案。这看起来不错!我将尝试一下这个想法是让sql语句与事务一起执行。DoAction方法将创建一个事务,并将其用于Lambda块中的所有查询。不知道这是否有意义。@AlexanderFuchs:是的,这是有意义的,但是不清楚为什么需要将
数据
传递到方法中,而不是在闭包中仅引用它。我理解-我也做了同样的事情。然而,对于Console.WriteLine(string),我有两个合适的变量。数据以及txt。这可能会让其他团队成员感到困惑。@AlexanderFuchs:这是一个有点让人困惑的方法-为什么
DoAction
负责计算一个新值并执行一个操作?如果不了解您真正想要实现的目标,就很难判断最佳解决方案是什么,但是使用
ref
参数和闭包对我来说似乎是个坏主意。对不起,在Lambda之前我不了解解决方案。这看起来不错!我要试试这个主意