Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rule S3966: Objects should not be disposed more than once #209

Closed
Evangelink opened this issue Apr 13, 2017 · 5 comments
Closed

Rule S3966: Objects should not be disposed more than once #209

Evangelink opened this issue Apr 13, 2017 · 5 comments
Milestone

Comments

@Evangelink
Copy link
Contributor

Evangelink commented Apr 13, 2017

Implements RSPEC-3966: Objects should not be disposed more than once

Contributes to MMF-963.

@Evangelink Evangelink added this to the 6.0 milestone Apr 13, 2017
@jccollet jccollet modified the milestones: 6.1, 6.0 Apr 20, 2017
@valhristov valhristov modified the milestones: 5.11, near-future May 5, 2017
@Evangelink Evangelink modified the milestones: 6.2, near-future Jun 30, 2017
@valhristov valhristov self-assigned this Jul 11, 2017
@nielsenko
Copy link

From https://docs.microsoft.com/en-us/dotnet/api/system.idisposable.dispose?redirectedfrom=MSDN&view=netframework-4.8#System_IDisposable_Dispose

If an object's Dispose method is called more than once, the object must ignore all calls after the first one. The object must not throw an exception if its Dispose method is called multiple times. Instance methods other than Dispose can throw an ObjectDisposedException when resources are already disposed.

So double dispose is explicitly supported by the IDispose contract. So why in the world do you prefer the try-catch-using combo. It makes the code longer and harder to read, especially compared to C# 8 (https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#using-declarations).

I know I can disable this rule, but I fail to comprehend why you would make this a default?

@nielsenko
Copy link

nielsenko commented Apr 24, 2019

I suppose you blindy implemented CA2202 from FxCop, that Roslyn explicitly decided against porting (see dotnet/roslyn-analyzers#528). See http://blogs.msdn.com/b/tilovell/archive/2014/02/12/the-worst-code-analysis-rule-that-s-recommended-ca2202.aspx for a true rant.

@ericjohannsen
Copy link

ericjohannsen commented Oct 5, 2020

The example of non-compliant code you provide is incorrect. StreamWriter.Dispose() does not call Dispose() on the underlying stream. It does call .Close() if the underlying stream is closeable, but that isn't the same thing. There is nothing wrong with a closed stream subsequently being disposed of.

https://github.com/microsoft/referencesource/blob/master/mscorlib/system/io/streamwriter.cs

For reference, here's the example you provide:

using (Stream stream = new FileStream("file.txt", FileMode.OpenOrCreate))
{
    using (StreamWriter writer = new StreamWriter(stream))  // Noncompliant: 'stream' will be disposed twice
    {
        // Use the writer object...
    }
}

@costin-zaharia-sonarsource
Copy link
Member

Hi @ericjohannsen,

indeed, the rule description provides an incorrect example for non-compliant code. I've added an issue and you can follow the progress here: #3644

Thanks for your feedback!

@costin-zaharia-sonarsource
Copy link
Member

Considering the feedback received for this rule we decided to:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants