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之前我不了解解决方案。这看起来不错!我要试试这个主意