Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Resharper to Identify Instances of IDisposable [duplicate]

Tags:

c#

.net

resharper

Can Resharper (v 7.1.3) help identify code that does not apply the "using" keyword when instantiating objects that implement IDisposable (i.e. SqlConnection, StreamReader)?

like image 811
kyletme Avatar asked Jul 12 '13 22:07

kyletme


1 Answers

ReSharper alone cannot do this.

FXCop cannot do this either, unfortunately. FXCop can warn about types that contain fields of types that implement IDisposable, but the type that contains them does not implement IDisposable. This is not what is being asked for here.

What you need is Visual Studio 2012 and then enable the Code Analysis engine to work its magic on your code. Make sure to enable a ruleset that contains the rule.

enable code analysis

Specifically you want to enable the CA2000 warning:

CA2000

after enabling this, and writing code like this:

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var stream = new MemoryStream();
        }
    }
}

you get this:

d:\Dev\VS.NET\ConsoleApplication1\ConsoleApplication1\Program.cs(14): warning : CA2000 : Microsoft.Reliability : In method 'Program.Main(string[])', call System.IDisposable.Dispose on object 'stream' before all references to it are out of scope.

Note: This will in some cases create both false negatives and false positives. First, the rule detects, and does not warn about the fact that you return such an object.

However, in the method where you get back the object, it will only call out the fact that you don't dispose it in some cases.

Specifically, this will create the warning:

static void Main(string[] args)
{
    var stream = CreateStream(); // warning here
}

private static MemoryStream CreateStream()
{
    return new MemoryStream();
}

whereas this will not:

static void Main(string[] args)
{
    var stream = GetStream(); // NO warning here
}

private static MemoryStream GetStream()
{
    return new MemoryStream();
}

The rule seems to detect that Create is a prefix for a factory method, so it falls upon the caller to dispose of the object, whereas Get is not such a prefix, so it falls upon the method being called to dispose of it, but since it returns the object, it doesn't have that responsibility either.

like image 111
Lasse V. Karlsen Avatar answered Sep 28 '22 16:09

Lasse V. Karlsen