Last active
May 1, 2017 16:59
-
-
Save timdetering/b99bc162443d95ed6f9e5e62e03bbefc to your computer and use it in GitHub Desktop.
IDisposable, Done Right
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace DisposableExample | |
{ | |
//------------------------------------------------------------------- | |
/// <summary> | |
/// Provides the base implementation for the <see cref="T:System.IDisposable"/> interface. | |
/// </summary> | |
/// <seealso cref="https://gist.github.com/timdetering/b99bc162443d95ed6f9e5e62e03bbefc"/> | |
/// <seealso cref="https://gist.github.com/thinktainer/5633464"/> | |
/// <seealso cref="https://lostechies.com/chrispatterson/2012/11/29/idisposable-done-right/"/> | |
/// <seealso cref="https://www.codeproject.com/Articles/15360/Implementing-IDisposable-and-the-Dispose-Pattern-P"/> | |
/// <seealso cref="https://gist.github.com/YTsalko/3959764239beb59051f83c6a132c022f"/> | |
/// <seealso cref="https://gist.github.com/fallenidol/5c990b56454b053b0f31b6b497d76ba9"/> | |
//------------------------------------------------------------------- | |
public class DisposableClass : IDisposable | |
{ | |
public DisposableClass() | |
{ | |
// | |
// When an object’s constructor throws an exception, the runtime considers the object to have never | |
// existed. And while the GC will release any object allocated by the constructor, it will not call the | |
// Dispose method on any disposable objects. | |
// Therefore it is the responsiblity of the object creating references to managed objects in the | |
// constructor (or even more importantly, unmanaged objects that consume limited system resources, such | |
// as file handles, socket handles, or threads). It should ensure to dispose of those resources in the | |
// case of a constructor exception by using a try/catch block. | |
// | |
} | |
//------------------------------------------------------------------- | |
/// <summary> | |
/// Releases unmanaged resources and performs other cleanup operations before the object is reclaimed by garbage collection. | |
/// Allows this object to attempt to free resources and perform other cleanup operations before it is reclaimed by garbage collection. | |
/// </summary> | |
//------------------------------------------------------------------- | |
~DisposableClass() | |
{ | |
this.Dispose(false); | |
} | |
//------------------------------------------------------------------- | |
/// <summary> | |
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. | |
/// Releases all resources used by the object. | |
/// </summary> | |
//------------------------------------------------------------------- | |
public void Dispose() | |
{ | |
this.Dispose(true); | |
GC.SuppressFinalize(this); | |
} | |
//------------------------------------------------------------------- | |
/// <summary> | |
/// Releases the unmanaged resources used by the component and optionally releases the managed resources. | |
/// </summary> | |
/// <param name="disposeManaged"> | |
/// <b>true</b> if managed resources should be disposed; otherwise, <b>false</b>. | |
/// </param> | |
/// <remarks> | |
/// This method is called by the public <see cref="Dispose"/> method and the Finalize method. Dispose invokes the protected Dispose(Boolean) method with the <i>disposeManaged</i> parameter set to true. Finalize invokes Dispose(Boolean) with <i>disposeManaged</i> set to false. | |
/// </remarks> | |
/// <seealso href="http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx"/> | |
//------------------------------------------------------------------- | |
protected virtual void Dispose(bool disposeManaged) | |
{ | |
if (false == _isDisposed) | |
{ | |
try | |
{ | |
if (true == disposeManaged) | |
{ | |
// free other managed objects that implement | |
// IDisposable only | |
} | |
// release any unmanaged objects | |
// set the object references to null | |
} | |
finally | |
{ | |
_isDisposed = true; | |
} | |
} | |
} | |
//------------------------------------------------------------------- | |
/// <summary> | |
/// Validate the object instance has not been disposed. | |
/// </summary> | |
//------------------------------------------------------------------- | |
protected void ValidateNotDisposed() | |
{ | |
if (true == _isDisposed) | |
{ | |
throw new ObjectDisposedException(this.GetType().Name); | |
} | |
} | |
private bool _isDisposed; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment