FxCop(/VS2010 代码分析),可以将方法结果标记为 IDisposable 的“现在调用者责任”吗?
Posted
技术标签:
【中文标题】FxCop(/VS2010 代码分析),可以将方法结果标记为 IDisposable 的“现在调用者责任”吗?【英文标题】:FxCop (/VS2010 Code Analysis), possible to flag method result as "callers responsibility now" for IDisposable? 【发布时间】:2011-12-12 10:12:05 【问题描述】:如果我写如下代码:
public void Execute()
var stream = new MemoryStream();
...
然后代码分析会将其标记为:
警告 1 CA2000:Microsoft.Reliability:在方法“ServiceUser.Execute()”中,在对对象“流”的所有引用超出范围之前调用 System.IDisposable.Dispose。 C:\Dev\VS.NET\DisposeTest\DisposeTest\ServiceUser.cs 14 DisposeTest
但是,如果我创建工厂模式,我仍然可能需要处理对象,但现在 FxCop/代码分析不会抱怨。 相反,它抱怨的是工厂方法,而不是调用它的代码。 (我想我有一个确实抱怨工厂方法的例子,但我在这里发布的那个没有,所以我把它删掉了)
有没有办法(例如使用属性)将 IDisposable 对象的职责从工厂方法转移到调用者身上?
获取此代码:
public class ServiceUser
public void Execute()
var stream = StreamFactory.GetStream();
Debug.WriteLine(stream.Length);
public static class StreamFactory
public static Stream GetStream()
return new MemoryStream();
在这种情况下,没有警告。我希望 FxCOP/CA 仍然抱怨我原来的方法。处理那个对象仍然是我的责任。
有什么方法可以告诉 FxCOP/CA?例如,我最近冒险研究了 ReSharper 提供的注释属性,以便告诉它的分析引擎信息,否则它无法理解。
所以我设想这样的事情:
public static class StreamFactory
[return: CallerResponsibility]
public static Stream GetStream()
return new MemoryStream();
或者这种设计方式有问题?
【问题讨论】:
【参考方案1】:FxCop 10(随 Windows 7 和 .NET 4.0 SDK 提供)和 Code Analysis 2010(随 Visual Studio Premium 及更高版本提供)之间存在差异。 Code Analysis 2010 有一个set of additional rules,其中包括高度改进的 IDisposable 规则版本。
使用 Visual Studio Premium 下的 Code Analysis 2010,工厂不会被标记(因为规则现在看到 IDisposable 变量返回到调用方法)。但是,由于规则的极端情况例外之一,接收方法也没有被标记。有一个方法名称列表会触发规则。如果将GetStream
方法重命名为CreateStream
,规则会突然触发:
Warning 4 CA2000 : Microsoft.Reliability : In method 'ServiceUser.Execute()',
call System.IDisposable.Dispose on object 'stream' before all references to it are out
of scope. BadProject\Class1.cs 14 BadProject
我无法找到有效的方法前缀列表。我已经尝试了一些,Create~
、Open~
触发了规则,许多其他你可能希望工作的,不要,包括Build~
、Make~
、Get~
。
另外还有一个long list of bugs surrounding this rule。该规则在 Visual Studio 2010 中进行了更改以触发更少的误报,但现在它有时会错过它应该标记的项目(并且会在以前的版本中标记)。没有足够的时间来修复 Visual Studio 2010 时间框架中的规则(查看错误报告 cmets)。
随着即将推出的 Roslyn 编译器,代码分析可能会出现重大升级,在此之前,预计只会有少量更新。 Visual Studio Dev11 的当前版本不会触发您想要的位置。
所以总结一下,没有你的属性不会有太大帮助,因为规则已经检测到你正在传递 IDisposable 作为返回值。因此,代码分析知道在返回之前将其处理掉是不好的。如果您使用的是未记录的命名规则,则会触发该规则。也许属性可以扩展命名规则,但我宁愿让微软真正修复实际规则。
我创建了一个connect bug 请求将命名指南记录在the rules documentation 中。
来自微软的评论:
Microsoft 于 2012 年 1 月 19 日上午 10:41 发布 你好,
感谢您抽出宝贵时间对此进行调查并提交文档更新请求。但是,在与我们的文档团队讨论后,我们决定不按照您的要求记录命名约定。
正如您在 *** 线程中指出的那样,该规则历来存在很多可靠性问题,并且关闭名称是为了减少误报数量而添加的内部实现细节。然而,这并不是关于开发人员应该如何命名他们的方法的说明性指南,它是在对常见编码实践进行调查后添加的。我们认为,长期的解决办法是提高规则的可靠性,而不是根据内部实施细节将命名指南添加到我们的公共文档中,这些细节将随着规则的改进而不断变化。
最好的问候, Visual Studio 代码分析团队
【讨论】:
以上是关于FxCop(/VS2010 代码分析),可以将方法结果标记为 IDisposable 的“现在调用者责任”吗?的主要内容,如果未能解决你的问题,请参考以下文章
有啥方法可以将 PhoenixAnalysis Engine 与 FxCop 10 一起使用?
Fxcop 针对 VS 2010 设计的自定义代码不适用于 VS 2012