dotnet/runtime

Analyzer for cases when the `Dispose()` pattern is introduced after the fact

Open

#70,188 创建于 2022年6月3日

在 GitHub 查看
 (3 评论) (1 反应) (0 负责人)C# (5,445 fork)batch import
api-approvedarea-System.Runtimecode-analyzercode-fixerhelp wanted

仓库指标

Star
 (17,886 star)
PR 合并指标
 (平均合并 12天 11小时) (30 天内合并 661 个 PR)

描述

Imagine we shipped a V1 like this:

// V1
public class Foo : IDisposable
{
    public virtual void Dispose();
}

The class isn't sealed so the class was supposed to have implemented the Dispose()-pattern but didn't due to oversight. We can't "unvirtualize" Dispose() in V2, but we can add the Dispose(bool disposing):

// V2
public class Foo : IDisposable
{
    public virtual void Dispose()
    {
       Dispose(true);
    }

    public virtual void Dispose(bool disposing)
    {
       if (disposing)
       {
          // Implementation from Dispose() in V1
       }
    }
}

Now imagine some code that was built against V1 looks as follows:

public class Bar : Foo
{
    public override void Dispose()
    {
        // Some code
    }
}

We'd like this code to raise a diagnostic:

'Bar' should override 'Dispose(bool)', not 'Dispose()'.

A code fixer should also be made available that changes Bar as follows:

public class Bar : Foo
{
    public override void Dispose(bool disposing)
    {
        if (disposing)
        {
            // Some code
        }
    }
}

Similarly, we should have a diagnostic that flags calls from the finalizer to Dispose() or Dispose(true) and replace it to Dispose(false):

public class SomeClass
{
    ~SomeClass()
    {
       Dispose();     // Warning
       Dispose(true); // Also warning
    }
}

A code fixer offer to change the call site to Dispose(false).

贡献者指南