code-analysis - FxCop(/VS2010 代码分析),可以将 IDisposable 的方法结果标记为 "callers responsibility now"吗?

标签 code-analysis idisposable fxcop chain-of-responsibility

如果我写下面的代码:

public void Execute()
{
    var stream = new MemoryStream();
    ...
}

然后代码分析会将其标记为:

Warning 1 CA2000 : Microsoft.Reliability : In method 'ServiceUser.Execute()', call System.IDisposable.Dispose on object 'stream' before all references to it are out of scope. 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();
    }
}

或者这种设计有问题吗?

最佳答案

FxCop 10(Windows 7 和 .NET 4.0 SDK 附带)和 Code Analysis 2010(Visual Studio Premium 及更高版本附带)之间存在差异。代码分析 2010 有一个 set of additional rules ,其中包括 IDisposable 规则的高度改进版本。

使用 Visual Studio Premium 下的 Code Analysis 2010,工厂不会被标记(因为规则现在看到 IDisposable 变量返回到调用方法)。但是,由于规则的极端情况之一,Receiving 方法也未被标记。有一个将导致规则触发的方法名称列表。如果将 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 时间范围内的规则(查看错误报告评论)。

随着即将推出的 Roslyn 编译器,代码分析可能会进行重大升级,在此之前预计只会有较小的更新。 Visual Studio Dev11 的当前版本不会在您想要的位置触发。

因此得出结论,您的属性不会有多大帮助,因为规则已经检测到您正在将 IDisposable 作为返回值传递。因此代码分析知道在返回之前处理它是不好的。如果您使用未记录的命名规则,该规则将触发。也许属性可以扩展命名规则,但我宁愿让 Microsoft 实际修复实际规则。

我创建了一个 connect bug要求在 the rules documentation 中记录命名指南.

来自微软的评论:

Posted by Microsoft on 1/19/2012 at 10:41 AM Hello,

Thank you for taking the time to investigate this and file the request for the documentation update. However after some discussion with our documentation team, we have decided to not document the naming convention as you requested.

As you indicated on the stackoverflow thread, there have historically been a lot of reliability issues with this rule, and keying off of the names was an internal implementation detail added to try to reduce the number of false positives. However this is not considered prescriptive guidance for how developers should name their methods, it was added after a survey of common coding practices. We believe the long-term fix is to improve the reliability of the rule, not add naming guidance to our public documentation based on internal implementation details that will continue to change as the rule is improved.

Best Regards, Visual Studio Code Analysis Team

关于code-analysis - FxCop(/VS2010 代码分析),可以将 IDisposable 的方法结果标记为 "callers responsibility now"吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8472685/

相关文章:

c# - 在 C# 中嵌套 "using"语句有什么问题吗?

c# - 静态 IDisposable 字典模式

.net - 在执行Process.Start()时,是否需要将其包装在using中?

.net - .Net 项目中的拼写检查消息字符串

c# - 正在分析 FxCop/代码分析警告 CA1506 : AvoidExcessiveClassCoupling

c# - VS2005代码分析: CA1063 (call dispose(true) and supress finalize) - with logging

c++ - 此目标不支持 VSC 运行代码分析 __float128

c++ - 警告 C6273 : Non-integer passed as _Param_(2) when an integer is required

c# - 如何分解我的代码行?

php - 有哪些工具可用于可视化类内依赖关系(例如 PHP)?