Skip to content

Latest commit

 

History

History
102 lines (79 loc) · 3.42 KB

IDISP008.md

File metadata and controls

102 lines (79 loc) · 3.42 KB

IDISP008

Don't assign member with injected and created disposables

Topic Value
Id IDISP008
Severity Warning
Enabled True
Category IDisposableAnalyzers.Correctness
Code AssignmentAnalyzer
FieldAndPropertyDeclarationAnalyzer

Description

Don't assign member with injected and created disposables It creates a confusing ownership situation.

Motivation

Example 1

using System;
using System.Threading;

public class Foo : IDisposable
{
    private readonly Mutex dependency;

    public Foo(Mutex dependency = null)
    {
        this.dependency = dependency ?? new Mutex();
    }
}

In the above example the field dependency is either assigned with the constructor parameter or new Mutex() if null. This means that we don't know if we created the mutex and are responsible for disposing it.

Example 2

using System.IO;

public class Foo
{
    public Stream Stream { get; set; } = File.OpenRead(string.Empty);
}

Above is a confusing situation about who is responsible for disposing the stream. It is created in the initializer but can later be assigned with streams created outside as there is no way to know what the property is assigned with. In this case removing the set; makes analysis trivial, then we only need to check initializer and constructor to figure out what the property is assigned with. Making it private set means we check all assignments within the class.

How to fix violations

Make members holding created disposables readonly or at least private set.

Example public field

public IDisposable Disposable; // could be assigned from the outside so we don't know if disposing it is safe.

Change to

public readonly IDisposable Disposable; // We can now check all places it is assigned and hopefully figure out if we should dispose

Example public property

public IDisposable Disposable { get; set; } // could be assigned from the outside so we don't know if disposing it is safe.

Change to

public readonly IDisposable Disposable { get; } // We can now check all places it is assigned and hopefully figure out if we should dispose

For members accepting injected disposables never assign a disposable that we create inside the class.

Configure severity

Via ruleset file.

Configure the severity per project, for more info see MSDN.

Via #pragma directive.

#pragma warning disable IDISP008 // Don't assign member with injected and created disposables
Code violating the rule here
#pragma warning restore IDISP008 // Don't assign member with injected and created disposables

Or put this at the top of the file to disable all instances.

#pragma warning disable IDISP008 // Don't assign member with injected and created disposables

Via attribute [SuppressMessage].

[System.Diagnostics.CodeAnalysis.SuppressMessage("IDisposableAnalyzers.Correctness", 
    "IDISP008:Don't assign member with injected and created disposables", 
    Justification = "Reason...")]