dotnet/runtime

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

Open

#70.188 geöffnet am 3. Juni 2022

Auf GitHub ansehen
 (3 Kommentare) (1 Reaktion) (0 zugewiesene Personen)C# (5.445 Forks)batch import
api-approvedarea-System.Runtimecode-analyzercode-fixerhelp wanted

Repository-Metriken

Stars
 (17.886 Stars)
PR-Merge-Metriken
 (Durchschn. Merge 12T 11h) (661 gemergte PRs in 30 T)

Beschreibung

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).

Contributor Guide