Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
216 lines (162 sloc) 18 KB
<Type Name="IDisposable" FullName="System.IDisposable">
<TypeSignature Language="C#" Value="public interface IDisposable" />
<TypeSignature Language="ILAsm" Value=".class public interface auto ansi abstract IDisposable" />
<TypeSignature Language="DocId" Value="T:System.IDisposable" />
<TypeSignature Language="VB.NET" Value="Public Interface IDisposable" />
<TypeSignature Language="C++ CLI" Value="public interface class IDisposable" />
<TypeSignature Language="F#" Value="type IDisposable = interface" />
<AssemblyInfo>
<AssemblyName>System.Runtime</AssemblyName>
<AssemblyVersion>4.0.0.0</AssemblyVersion>
<AssemblyVersion>4.0.10.0</AssemblyVersion>
<AssemblyVersion>4.0.20.0</AssemblyVersion>
<AssemblyVersion>4.1.0.0</AssemblyVersion>
<AssemblyVersion>4.2.0.0</AssemblyVersion>
<AssemblyVersion>4.2.1.0</AssemblyVersion>
</AssemblyInfo>
<AssemblyInfo>
<AssemblyName>mscorlib</AssemblyName>
<AssemblyVersion>1.0.5000.0</AssemblyVersion>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
<AssemblyVersion>2.0.5.0</AssemblyVersion>
<AssemblyVersion>4.0.0.0</AssemblyVersion>
</AssemblyInfo>
<AssemblyInfo>
<AssemblyName>netstandard</AssemblyName>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
<AssemblyVersion>2.1.0.0</AssemblyVersion>
</AssemblyInfo>
<Interfaces />
<Attributes>
<Attribute FrameworkAlternate="netframework-2.0;netframework-3.0;netframework-3.5;netframework-4.0;netframework-4.5;netframework-4.5.1;netframework-4.5.2;netframework-4.6;netframework-4.6.1;netframework-4.6.2;netframework-4.7;netframework-4.7.1;netframework-4.7.2;xamarinandroid-7.1;xamarinios-10.8;xamarinmac-3.0;netframework-4.8">
<AttributeName>System.Runtime.InteropServices.ComVisible(true)</AttributeName>
</Attribute>
</Attributes>
<Docs>
<summary>Provides a mechanism for releasing unmanaged resources.</summary>
<remarks>
<format type="text/markdown"><![CDATA[
## Remarks
The primary use of this interface is to release unmanaged resources. The garbage collector automatically releases the memory allocated to a managed object when that object is no longer used. However, it is not possible to predict when garbage collection will occur. Furthermore, the garbage collector has no knowledge of unmanaged resources such as window handles, or open files and streams.
Use the <xref:System.IDisposable.Dispose%2A> method of this interface to explicitly release unmanaged resources in conjunction with the garbage collector. The consumer of an object can call this method when the object is no longer needed.
> [!WARNING]
> It is a breaking change to add the <xref:System.IDisposable> interface to an existing class. Because pre-existing consumers of your type cannot call <xref:System.IDisposable.Dispose%2A>, you cannot be certain that unmanaged resources held by your type will be released.
Because the <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType> implementation is called by the consumer of a type when the resources owned by an instance are no longer needed, you should either wrap the managed object in a <xref:System.Runtime.InteropServices.SafeHandle> (the recommended alternative), or you should override <xref:System.Object.Finalize%2A?displayProperty=nameWithType> to free unmanaged resources in the event that the consumer forgets to call <xref:System.IDisposable.Dispose%2A>.
> [!IMPORTANT]
> In the .NET Framework, the C++ compiler supports deterministic disposal of resources and does not allow direct implementation of the <xref:System.IDisposable.Dispose%2A> method.
For a detailed discussion about how this interface and the <xref:System.Object.Finalize%2A?displayProperty=nameWithType> method are used, see the [Garbage Collection](~/docs/standard/garbage-collection/index.md) and [Implementing a Dispose Method](~/docs/standard/garbage-collection/implementing-dispose.md) topics.
## Using an object that implements IDisposable
If your app simply uses an object that implements the <xref:System.IDisposable> interface, you should call the object's <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType> implementation when you are finished using it. Depending on your programming language, you can do this in one of two ways:
- By using a language construct such as the `using` statement in C# and Visual Basic.
- By wrapping the call to the <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType> implementation in a `try`/`finally` block.
> [!NOTE]
> Documentation for types that implement <xref:System.IDisposable> note that fact and include a reminder to call its <xref:System.IDisposable.Dispose%2A> implementation.
<a name="Using"></a>
### The C# and Visual Basic Using statement
If your language supports a construct such as the [using](~/docs/csharp/language-reference/keywords/using.md) statement in C# and the [Using](~/docs/visual-basic/language-reference/statements/using-statement.md) statement in Visual Basic, you can use it instead of explicitly calling <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType> yourself. The following example uses this approach in defining a `WordCount` class that preserves information about a file and the number of words in it.
[!code-csharp[System.IDisposable#1](~/samples/snippets/csharp/VS_Snippets_CLR_System/system.idisposable/cs/calling1.cs#1)]
[!code-vb[System.IDisposable#1](~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.idisposable/vb/calling1.vb#1)]
The `using` statement is actually a syntactic convenience. At compile time, the language compiler implements the intermediate language (IL) for a `try`/`finally` block.
For more information about the `using` statement, see the [Using Statement](~/docs/visual-basic/language-reference/statements/using-statement.md) or [using Statement](~/docs/csharp/language-reference/keywords/using-statement.md) topics.
### The Try/Finally block
If your programming language does not support a construct like the `using` statement in C# or Visual Basic, or if you prefer not to use it, you can call the <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType> implementation from the `finally` block of a `try`/`finally` statement. The following example replaces the `using` block in the previous example with a `try`/`finally` block.
[!code-csharp[System.IDisposable#2](~/samples/snippets/csharp/VS_Snippets_CLR_System/system.idisposable/cs/calling2.cs#2)]
[!code-vb[System.IDisposable#2](~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.idisposable/vb/calling2.vb#2)]
For more information about the `try`/`finally` pattern, see [Try...Catch...Finally Statement](~/docs/visual-basic/language-reference/statements/try-catch-finally-statement.md), [try-finally](~/docs/csharp/language-reference/keywords/try-finally.md), or [try-finally Statement](https://msdn.microsoft.com/library/514400c1-c322-4bf3-9e48-3047240b8a82).
## Implementing IDisposable
You should implement <xref:System.IDisposable> only if your type uses unmanaged resources directly. The consumers of your type can call your <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType> implementation to free resources when the instance is no longer needed. To handle cases in which they fail to call <xref:System.IDisposable.Dispose%2A>, you should either use a class derived from <xref:System.Runtime.InteropServices.SafeHandle> to wrap the unmanaged resources, or you should override the <xref:System.Object.Finalize%2A?displayProperty=nameWithType> method for a reference type. In either case, you use the <xref:System.IDisposable.Dispose%2A> method to perform whatever cleanup is necessary after using the unmanaged resources, such as freeing, releasing, or resetting the unmanaged resources.
> [!IMPORTANT]
> If you are defining a base class that uses unmanaged resources and that either has, or is likely to have, subclasses that should be disposed, you should implement the <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType> method and provide a second overload of `Dispose`, as discussed in the next section.
<a name="BaseClasses"></a>
## IDisposable and the inheritance hierarchy
A base class with subclasses that should be disposable must implement <xref:System.IDisposable> as follows. You should use this pattern whenever you implement <xref:System.IDisposable> on any type that isn't `sealed` (`NotInheritable` in Visual Basic).
- It should provide one public, non-virtual <xref:System.IDisposable.Dispose> method and a protected virtual `Dispose(Boolean disposing)` method.
- The <xref:System.IDisposable.Dispose> method must call `Dispose(true)` and should suppress finalization for performance.
- The base type should not include any finalizers.
The following code fragment reflects the dispose pattern for base classes. It assumes that your type does not override the <xref:System.Object.Finalize%2A?displayProperty=nameWithType> method.
[!code-csharp[System.IDisposable#3](~/samples/snippets/csharp/VS_Snippets_CLR_System/system.idisposable/cs/base1.cs#3)]
[!code-vb[System.IDisposable#3](~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.idisposable/vb/base1.vb#3)]
If you do override the <xref:System.Object.Finalize%2A?displayProperty=nameWithType> method, your class should implement the following pattern.
[!code-csharp[System.IDisposable#5](~/samples/snippets/csharp/VS_Snippets_CLR_System/system.idisposable/cs/base2.cs#5)]
[!code-vb[System.IDisposable#5](~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.idisposable/vb/base2.vb#5)]
Subclasses should implement the disposable pattern as follows:
- They must override `Dispose(Boolean)` and call the base class `Dispose(Boolean)` implementation.
- They can provide a finalizer if needed. The finalizer must call `Dispose(false)`.
Note that derived classes do not themselves implement the <xref:System.IDisposable> interface and do not include a parameterless <xref:System.IDisposable.Dispose%2A> method. They only override the base class `Dispose(Boolean)` method.
The following code fragment reflects the dispose pattern for derived classes. It assumes that your type does not override the <xref:System.Object.Finalize%2A?displayProperty=nameWithType> method.
[!code-csharp[System.IDisposable#4](~/samples/snippets/csharp/VS_Snippets_CLR_System/system.idisposable/cs/derived1.cs#4)]
[!code-vb[System.IDisposable#4](~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.idisposable/vb/derived1.vb#4)]
## Examples
The following example demonstrates how to create a resource class that implements the <xref:System.IDisposable> interface.
[!code-cpp[System.IDisposable.Dispose Example#1](~/samples/snippets/cpp/VS_Snippets_CLR_System/system.IDisposable.Dispose Example/CPP/idisposabledispose.cpp#1)]
[!code-csharp[System.IDisposable.Dispose Example#1](~/samples/snippets/csharp/VS_Snippets_CLR_System/system.IDisposable.Dispose Example/CS/idisposabledispose.cs#1)]
[!code-vb[System.IDisposable.Dispose Example#1](~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.IDisposable.Dispose Example/VB/idisposabledispose.vb#1)]
]]></format>
</remarks>
<altmember cref="T:Microsoft.Win32.SafeHandles.SafeFileHandle" />
<related type="Article" href="~/docs/standard/garbage-collection/implementing-dispose.md">Implementing a Dispose Method</related>
</Docs>
<Members>
<Member MemberName="Dispose">
<MemberSignature Language="C#" Value="public void Dispose ();" />
<MemberSignature Language="ILAsm" Value=".method public hidebysig newslot virtual instance void Dispose() cil managed" />
<MemberSignature Language="DocId" Value="M:System.IDisposable.Dispose" />
<MemberSignature Language="VB.NET" Value="Public Sub Dispose ()" />
<MemberSignature Language="C++ CLI" Value="public:&#xA; void Dispose();" />
<MemberSignature Language="F#" Value="abstract member Dispose : unit -&gt; unit" Usage="iDisposable.Dispose " />
<MemberType>Method</MemberType>
<AssemblyInfo>
<AssemblyName>System.Runtime</AssemblyName>
<AssemblyVersion>4.0.0.0</AssemblyVersion>
<AssemblyVersion>4.0.10.0</AssemblyVersion>
<AssemblyVersion>4.0.20.0</AssemblyVersion>
<AssemblyVersion>4.1.0.0</AssemblyVersion>
<AssemblyVersion>4.2.0.0</AssemblyVersion>
<AssemblyVersion>4.2.1.0</AssemblyVersion>
</AssemblyInfo>
<AssemblyInfo>
<AssemblyName>mscorlib</AssemblyName>
<AssemblyVersion>1.0.5000.0</AssemblyVersion>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
<AssemblyVersion>2.0.5.0</AssemblyVersion>
<AssemblyVersion>4.0.0.0</AssemblyVersion>
</AssemblyInfo>
<AssemblyInfo>
<AssemblyName>netstandard</AssemblyName>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
<AssemblyVersion>2.1.0.0</AssemblyVersion>
</AssemblyInfo>
<ReturnValue>
<ReturnType>System.Void</ReturnType>
</ReturnValue>
<Parameters />
<Docs>
<summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
<remarks>
<format type="text/markdown"><![CDATA[
## Remarks
Use this method to close or release unmanaged resources such as files, streams, and handles held by an instance of the class that implements this interface. By convention, this method is used for all tasks associated with freeing resources held by an object, or preparing an object for reuse.
> [!WARNING]
> If you are using a class that implements the <xref:System.IDisposable> interface, you should call its <xref:System.IDisposable.Dispose%2A> implementation when you are finished using the class. For more information, see the "Using an object that implements IDisposable" section in the <xref:System.IDisposable> topic.
When implementing this method, ensure that all held resources are freed by propagating the call through the containment hierarchy. For example, if an object A allocates an object B, and object B allocates an object C, then A's <xref:System.IDisposable.Dispose%2A> implementation must call <xref:System.IDisposable.Dispose%2A> on B, which must in turn call <xref:System.IDisposable.Dispose%2A> on C.
> [!IMPORTANT]
> The C++ compiler supports deterministic disposal of resources and does not allow direct implementation of the <xref:System.IDisposable.Dispose%2A> method.
An object must also call the <xref:System.IDisposable.Dispose%2A> method of its base class if the base class implements <xref:System.IDisposable>. For more information about implementing <xref:System.IDisposable> on a base class and its subclasses, see the "IDisposable and the inheritance hierarchy" section in the <xref:System.IDisposable> topic.
If an object's <xref:System.IDisposable.Dispose%2A> 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 <xref:System.IDisposable.Dispose%2A> method is called multiple times. Instance methods other than <xref:System.IDisposable.Dispose%2A> can throw an <xref:System.ObjectDisposedException> when resources are already disposed.
Users might expect a resource type to use a particular convention to denote an allocated state versus a freed state. An example of this is stream classes, which are traditionally thought of as open or closed. The implementer of a class that has such a convention might choose to implement a public method with a customized name, such as `Close`, that calls the <xref:System.IDisposable.Dispose%2A> method.
Because the <xref:System.IDisposable.Dispose%2A> method must be called explicitly, there is always a danger that the unmanaged resources will not be released, because the consumer of an object fails to call its <xref:System.IDisposable.Dispose%2A> method. There are two ways to avoid this:
- Wrap the managed resource in an object derived from <xref:System.Runtime.InteropServices.SafeHandle?displayProperty=nameWithType>. Your <xref:System.IDisposable.Dispose%2A> implementation then calls the <xref:System.IDisposable.Dispose%2A> method of the <xref:System.Runtime.InteropServices.SafeHandle?displayProperty=nameWithType> instances. For more information, see "The SafeHandle alternative" section in the <xref:System.Object.Finalize%2A?displayProperty=nameWithType> topic.
- Implement a finalizer to free resources when <xref:System.IDisposable.Dispose%2A> is not called. By default, the garbage collector automatically calls an object's finalizer before reclaiming its memory. However, if the <xref:System.IDisposable.Dispose%2A> method has been called, it is typically unnecessary for the garbage collector to call the disposed object's finalizer. To prevent automatic finalization, <xref:System.IDisposable.Dispose%2A> implementations can call the <xref:System.GC.SuppressFinalize%2A?displayProperty=nameWithType> method.
When you use an object that accesses unmanaged resources, such as a <xref:System.IO.StreamWriter>, a good practice is to create the instance with a `using` statement. The `using` statement automatically closes the stream and calls <xref:System.IDisposable.Dispose%2A> on the object when the code that is using it has completed. For an example, see the <xref:System.IO.StreamWriter> class.
## Examples
The following example shows how you can implement the <xref:System.IDisposable.Dispose%2A> method.
[!code-cpp[System.IDisposable.Dispose Example#1](~/samples/snippets/cpp/VS_Snippets_CLR_System/system.IDisposable.Dispose Example/CPP/idisposabledispose.cpp#1)]
[!code-csharp[System.IDisposable.Dispose Example#1](~/samples/snippets/csharp/VS_Snippets_CLR_System/system.IDisposable.Dispose Example/CS/idisposabledispose.cs#1)]
[!code-vb[System.IDisposable.Dispose Example#1](~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.IDisposable.Dispose Example/VB/idisposabledispose.vb#1)]
]]></format>
</remarks>
<related type="Article" href="~/docs/standard/garbage-collection/implementing-dispose.md">Implementing a Dispose Method</related>
</Docs>
</Member>
</Members>
</Type>
You can’t perform that action at this time.