summaryrefslogtreecommitdiff
path: root/src/mscorlib/shared/System/IDisposable.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/shared/System/IDisposable.cs')
-rw-r--r--src/mscorlib/shared/System/IDisposable.cs60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/mscorlib/shared/System/IDisposable.cs b/src/mscorlib/shared/System/IDisposable.cs
new file mode 100644
index 0000000000..24f0740edc
--- /dev/null
+++ b/src/mscorlib/shared/System/IDisposable.cs
@@ -0,0 +1,60 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*============================================================
+**
+** Interface: IDisposable
+**
+**
+** Purpose: Interface for assisting with deterministic finalization.
+**
+**
+===========================================================*/
+
+namespace System
+{
+ // IDisposable is an attempt at helping to solve problems with deterministic
+ // finalization. The GC of course doesn't leave any way to deterministically
+ // know when a finalizer will run. This forces classes that hold onto OS
+ // resources or some sort of important state (such as a FileStream or a
+ // network connection) to provide a Close or Dispose method so users can
+ // run clean up code deterministically. We have formalized this into an
+ // interface with one method. Classes may privately implement IDisposable and
+ // provide a Close method instead, if that name is by far the expected name
+ // for objects in that domain (ie, you don't Dispose of a FileStream, you Close
+ // it).
+ //
+ // This interface could be theoretically used as a marker by a compiler to
+ // ensure a disposable object has been cleaned up along all code paths if it's
+ // been allocated in that method, though in practice any compiler that
+ // draconian may tick off any number of people. Perhaps an external tool (like
+ // like Purify or BoundsChecker) could do this. Instead, C# has added a using
+ // clause, which will generate a try/finally statement where the resource
+ // passed into the using clause will always have it's Dispose method called.
+ // Syntax is using(FileStream fs = ...) { .. };
+ //
+ // Dispose should meet the following conditions:
+ // 1) Be safely callable multiple times
+ // 2) Release any resources associated with the instance
+ // 3) Call the base class's Dispose method, if necessary
+ // 4) Suppress finalization of this class to help the GC by reducing the
+ // number of objects on the finalization queue.
+ // 5) Dispose shouldn't generally throw exceptions, except for very serious
+ // errors that are particularly unexpected. (ie, OutOfMemoryException)
+ // Ideally, nothing should go wrong with your object by calling Dispose.
+ //
+ // If possible, a class should define a finalizer that calls Dispose.
+ // However, in many situations, this is impractical. For instance, take the
+ // classic example of a Stream and a StreamWriter (which has an internal
+ // buffer of data to write to the Stream). If both objects are collected
+ // before Close or Dispose has been called on either, then the GC may run the
+ // finalizer for the Stream first, before the StreamWriter. At that point, any
+ // data buffered by the StreamWriter cannot be written to the Stream. In this
+ // case, it doesn't make much sense to provide a finalizer on the StreamWriter
+ // since you cannot solve this problem correctly.
+ public interface IDisposable
+ {
+ void Dispose();
+ }
+}