|
64 | 64 | ## Using an object that implements IDisposable |
65 | 65 | 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: |
66 | 66 | |
67 | | -- By using a language construct such as the `using` statement in C# and Visual Basic. |
| 67 | +- By using a language construct such as the `using` statement in C# and Visual Basic, and the `use` statement or `using` function in F#. |
68 | 68 | |
69 | 69 | - By wrapping the call to the <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType> implementation in a `try`/`finally` block. |
70 | 70 | |
71 | 71 | > [!NOTE] |
72 | 72 | > Documentation for types that implement <xref:System.IDisposable> note that fact and include a reminder to call its <xref:System.IDisposable.Dispose%2A> implementation. |
73 | 73 | |
74 | 74 | <a name="Using"></a> |
75 | | -### The C# and Visual Basic Using statement |
76 | | - If your language supports a construct such as the [using](/dotnet/csharp/language-reference/keywords/using) statement in C# and the [Using](/dotnet/visual-basic/language-reference/statements/using-statement) 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. |
| 75 | +### The C#, F#, and Visual Basic Using statement |
| 76 | + If your language supports a construct such as the [using](/dotnet/csharp/language-reference/keywords/using) statement in C#, the [Using](/dotnet/visual-basic/language-reference/statements/using-statement) statement in Visual Basic, or the [use](/dotnet/fsharp/language-reference/resource-management-the-use-keyword) staatement in F#, 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. |
77 | 77 | |
78 | 78 | :::code language="csharp" source="~/snippets/csharp/System/IDisposable/Overview/calling1.cs" id="Snippet1"::: |
| 79 | + :::code language="fsharp" source="~/snippets/fsharp/System/IDisposable/Overview/calling1.fs" id="Snippet1"::: |
79 | 80 | :::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.idisposable/vb/calling1.vb" id="Snippet1"::: |
80 | 81 | |
81 | | - The `using` statement is actually a syntactic convenience. At compile time, the language compiler implements the intermediate language (IL) for a `try`/`finally` block. |
| 82 | + The `using` statement (`use` expression in F#) is actually a syntactic convenience. At compile time, the language compiler implements the intermediate language (IL) for a `try`/`finally` block. |
82 | 83 | |
83 | 84 | For more information about the `using` statement, see the [Using Statement](/dotnet/visual-basic/language-reference/statements/using-statement) or [using Statement](/dotnet/csharp/language-reference/keywords/using-statement) topics. |
84 | 85 | |
85 | 86 | ### The Try/Finally block |
86 | | - 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. |
| 87 | + If your programming language does not support a construct like the `using` statement in C# or Visual Basic, or the `use` statement in F#, 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. |
87 | 88 | |
88 | 89 | :::code language="csharp" source="~/snippets/csharp/System/IDisposable/Overview/calling2.cs" id="Snippet2"::: |
| 90 | + :::code language="fsharp" source="~/snippets/fsharp/System/IDisposable/Overview/calling2.fs" id="Snippet2"::: |
89 | 91 | :::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.idisposable/vb/calling2.vb" id="Snippet2"::: |
90 | 92 | |
91 | | - For more information about the `try`/`finally` pattern, see [Try...Catch...Finally Statement](/dotnet/visual-basic/language-reference/statements/try-catch-finally-statement), [try-finally](/dotnet/csharp/language-reference/keywords/try-finally), or [try-finally Statement](/cpp/c-language/try-finally-statement-c). |
| 93 | + For more information about the `try`/`finally` pattern, see [Try...Catch...Finally Statement](/dotnet/visual-basic/language-reference/statements/try-catch-finally-statement), [try-finally](/dotnet/csharp/language-reference/keywords/try-finally), [try...finally Expression](/dotnet/fsharp/language-reference/exception-handling/the-try-finally-expression), or [try-finally Statement](/cpp/c-language/try-finally-statement-c). |
92 | 94 | |
93 | 95 | ## Implementing IDisposable |
94 | 96 | You should implement <xref:System.IDisposable> if your type uses unmanaged resources directly or if you wish to use disposable resources yourself. 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. For more information about implementing <xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType>, see [the Dispose(bool) method overload](/dotnet/standard/garbage-collection/implementing-dispose#the-disposebool-method-overload). |
|
109 | 111 | 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. |
110 | 112 | |
111 | 113 | :::code language="csharp" source="~/snippets/csharp/System/IDisposable/Overview/base1.cs" id="Snippet3"::: |
| 114 | + :::code language="fsharp" source="~/snippets/fsharp/System/IDisposable/Overview/base1.fs" id="Snippet3"::: |
112 | 115 | :::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.idisposable/vb/base1.vb" id="Snippet3"::: |
113 | 116 | |
114 | 117 | If you do override the <xref:System.Object.Finalize%2A?displayProperty=nameWithType> method, your class should implement the following pattern. |
115 | 118 | |
116 | 119 | :::code language="csharp" source="~/snippets/csharp/System/IDisposable/Overview/base2.cs" id="Snippet5"::: |
| 120 | + :::code language="fsharp" source="~/snippets/fsharp/System/IDisposable/Overview/base2.fs" id="Snippet5"::: |
117 | 121 | :::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.idisposable/vb/base2.vb" id="Snippet5"::: |
118 | 122 | |
119 | 123 | Subclasses should implement the disposable pattern as follows: |
|
127 | 131 | 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. |
128 | 132 | |
129 | 133 | :::code language="csharp" source="~/snippets/csharp/System/IDisposable/Overview/derived1.cs" id="Snippet4"::: |
| 134 | + :::code language="fsharp" source="~/snippets/fsharp/System/IDisposable/Overview/derived1.fs" id="Snippet4"::: |
130 | 135 | :::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.idisposable/vb/derived1.vb" id="Snippet4"::: |
131 | 136 | |
132 | 137 | |
|
136 | 141 | |
137 | 142 | :::code language="cpp" source="~/snippets/cpp/VS_Snippets_CLR_System/system.IDisposable.Dispose Example/CPP/idisposabledispose.cpp" id="Snippet1"::: |
138 | 143 | :::code language="csharp" source="~/snippets/csharp/System/IDisposable/Overview/idisposabledispose.cs" id="Snippet1"::: |
| 144 | + :::code language="fsharp" source="~/snippets/fsharp/System/IDisposable/Overview/idisposabledispose.fs" id="Snippet1"::: |
139 | 145 | :::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.IDisposable.Dispose Example/VB/idisposabledispose.vb" id="Snippet1"::: |
140 | 146 | |
141 | 147 | ]]></format> |
|
217 | 223 | |
218 | 224 | :::code language="cpp" source="~/snippets/cpp/VS_Snippets_CLR_System/system.IDisposable.Dispose Example/CPP/idisposabledispose.cpp" id="Snippet1"::: |
219 | 225 | :::code language="csharp" source="~/snippets/csharp/System/IDisposable/Overview/idisposabledispose.cs" id="Snippet1"::: |
| 226 | + :::code language="fsharp" source="~/snippets/fsharp/System/IDisposable/Overview/idisposabledispose.fs" id="Snippet1"::: |
220 | 227 | :::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.IDisposable.Dispose Example/VB/idisposabledispose.vb" id="Snippet1"::: |
221 | 228 | |
222 | 229 | ]]></format> |
|
0 commit comments