Skip to content

Instantly share code, notes, and snippets.

@Protiguous
Last active September 11, 2021 09:33
Show Gist options
  • Save Protiguous/18ead32a1b606e5e9d6bfcd05fdcf11b to your computer and use it in GitHub Desktop.
Save Protiguous/18ead32a1b606e5e9d6bfcd05fdcf11b to your computer and use it in GitHub Desktop.
A different [easier] way of disposing objects.
// Copyright © Protiguous. All Rights Reserved.
//
// This entire copyright notice and license must be retained and must be kept visible in any binaries, libraries, repositories, or source code (directly or derived) from our binaries, libraries, projects, solutions, or applications.
//
// All source code belongs to Protiguous@Protiguous.com unless otherwise specified or the original license has been overwritten by formatting. (We try to avoid it from happening, but it does accidentally happen.)
//
// Any unmodified portions of source code gleaned from other sources still retain their original license and our thanks goes to those Authors.
// If you find your code unattributed in this source code, please let us know so we can properly attribute you and include the proper license and/or copyright(s).
// If you want to use any of our code in a commercial project, you must contact Protiguous@Protiguous.com for permission, license, and a quote.
//
// Donations, payments, and royalties are accepted via bitcoin: 1Mad8TxTqxKnMiHuZxArFvX8BuFEB9nqX2 and PayPal: Protiguous@Protiguous.com
//
// ====================================================================
// Disclaimer: Usage of the source code or binaries is AS-IS.
// No warranties are expressed, implied, or given.
// We are NOT responsible for Anything You Do With Our Code.
// We are NOT responsible for Anything You Do With Our Executables.
// We are NOT responsible for Anything You Do With Your Computer.
// ====================================================================
//
// Contact us by email if you have any questions, helpful criticism, or if you would like to use our code in your project(s).
// For business inquiries, please contact me at Protiguous@Protiguous.com.
// Our software can be found at "https://Protiguous.Software/"
// Our GitHub address is "https://github.com/Protiguous".
//
// File "ABetterClassDispose.cs" last touched on 2021-09-11 at 3:26 AM by Protiguous.
#nullable enable
namespace Librainian.Utilities.Disposables {
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;
/// <summary>
/// <para>A class for easier implementation the proper <see cref="IDisposable" /> pattern.</para>
/// <para>Implement overrides on <see cref="DisposeManaged" />, and <see cref="DisposeNative" /> as needed.</para>
/// <code></code>
/// </summary>
/// <remarks>ABCD (hehe).</remarks>
/// <copyright>Created by Protiguous.</copyright>
public abstract class ABetterClassDispose : IABetterClassDispose {
private Int32 _hasDisposedManaged;
private Int32 _hasDisposedNative;
private Int32 _hasSuppressedFinalize;
public Boolean HasDisposedManaged {
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
get => Interlocked.CompareExchange( ref this._hasDisposedManaged, 0, 0 ) == 1;
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
set {
if ( this.HasDisposedManaged ) {
return; //don't allow the setting to be changed once it has been set.
}
_ = Interlocked.Exchange( ref this._hasDisposedManaged, value ? 1 : 0 );
}
}
public Boolean HasDisposedNative {
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
get => Interlocked.CompareExchange( ref this._hasDisposedNative, 0, 0 ) == 1;
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
set {
if ( this.HasDisposedNative ) {
return; //don't allow the setting to be changed once it has been set.
}
_ = Interlocked.Exchange( ref this._hasDisposedNative, value ? 1 : 0 );
}
}
public Boolean HasSuppressedFinalize {
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
get => Interlocked.CompareExchange( ref this._hasSuppressedFinalize, 0, 0 ) == 1;
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
set {
if ( this.HasSuppressedFinalize ) {
return; //don't allow the setting to be changed once it has been set.
}
_ = Interlocked.Exchange( ref this._hasSuppressedFinalize, value ? 1 : 0 );
}
}
/// <summary>Can be changed to a property, if desired.</summary>
public Boolean IsDisposed => this.HasDisposedManaged && this.HasDisposedNative;
/// <summary>
/// <para>
/// Disposes of managed resources, then unmanaged resources, and then calls <see cref="GC.SuppressFinalize" /> for
/// this object.
/// </para>
/// <para>Note: Calling <see cref="Dispose()" /> multiple times has no effect beyond the first call.</para>
/// </summary>
[DebuggerStepThrough]
public void Dispose() {
if ( !this.HasDisposedManaged ) {
try {
this.DisposeManaged(); //Any derived class should have overloaded this method and disposed of any managed objects inside.
}
catch ( Exception exception ) {
Debug.WriteLine( exception );
}
finally {
this.HasDisposedManaged = true;
}
}
if ( !this.HasDisposedNative ) {
try {
this.DisposeNative(); //Any derived class should overload this method.
}
catch ( Exception exception ) {
Debug.WriteLine( exception );
}
finally {
this.HasDisposedNative = true;
}
}
if ( this.IsDisposed && !this.HasSuppressedFinalize ) {
try {
GC.SuppressFinalize( this );
}
catch ( Exception exception ) {
Debug.WriteLine( exception );
}
finally {
this.HasSuppressedFinalize = true;
}
}
}
/// <summary>
/// Just calls <see cref="Dispose()" />. The parameter <paramref name="dispose" /> has no effect with this design.
/// </summary>
/// <param name="dispose"></param>
[DebuggerStepThrough]
public void Dispose( Boolean dispose ) => this.Dispose();
/// <summary>Override this method to dispose of any <see cref="IDisposable" /> managed fields or properties.</summary>
/// <code>using var bob = new DisposableType();</code>
[DebuggerStepThrough]
public virtual void DisposeManaged() { }
/// <summary>
/// Dispose of COM objects, handles, etc in this method.
/// </summary>
[DebuggerStepThrough]
public virtual void DisposeNative() =>
/*make this virtual so it is optional*/
this.HasDisposedNative = true;
~ABetterClassDispose() {
this.Dispose();
}
/*
/// <summary>Set via <see cref="SetDisposeHint" /> to help find if an object has not been disposed of properly.</summary>
[CanBeNull]
private String? DisposeHint { get; set; }
*/
/*
/// <summary>Call at any time to set a debugging hint as to the creator of this disposable.</summary>
/// <param name="hint"></param>
[Conditional( "DEBUG" )]
public void SetDisposeHint( [CanBeNull] String? hint ) => this.DisposeHint = hint;
*/
}
}
// Copyright © Protiguous. All Rights Reserved.
//
// This entire copyright notice and license must be retained and must be kept visible in any binaries, libraries, repositories, or source code (directly or derived) from our binaries, libraries, projects, solutions, or applications.
//
// All source code belongs to Protiguous@Protiguous.com unless otherwise specified or the original license has been overwritten by formatting. (We try to avoid it from happening, but it does accidentally happen.)
//
// Any unmodified portions of source code gleaned from other sources still retain their original license and our thanks goes to those Authors.
// If you find your code unattributed in this source code, please let us know so we can properly attribute you and include the proper license and/or copyright(s).
// If you want to use any of our code in a commercial project, you must contact Protiguous@Protiguous.com for permission, license, and a quote.
//
// Donations, payments, and royalties are accepted via bitcoin: 1Mad8TxTqxKnMiHuZxArFvX8BuFEB9nqX2 and PayPal: Protiguous@Protiguous.com
//
// ====================================================================
// Disclaimer: Usage of the source code or binaries is AS-IS.
// No warranties are expressed, implied, or given.
// We are NOT responsible for Anything You Do With Our Code.
// We are NOT responsible for Anything You Do With Our Executables.
// We are NOT responsible for Anything You Do With Your Computer.
// ====================================================================
//
// Contact us by email if you have any questions, helpful criticism, or if you would like to use our code in your project(s).
// For business inquiries, please contact me at Protiguous@Protiguous.com.
// Our software can be found at "https://Protiguous.Software/"
// Our GitHub address is "https://github.com/Protiguous".
//
// File "ABetterClassDisposeAsync.cs" last touched on 2021-09-11 at 3:29 AM by Protiguous.
namespace Librainian.Utilities.Disposables {
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
/// <summary>
/// <para>A class for easier implementation the proper <see cref="IDisposable" /> pattern.</para>
/// <para>Implement overrides on <see cref="DisposeManagedAsync" />, and <see cref="DisposeNativeAsync" /> as needed.</para>
/// <code></code>
/// </summary>
/// <remarks>ABCD (hehe).</remarks>
/// <copyright>Created by Protiguous.</copyright>
[NeedsTesting]
public abstract class ABetterClassDisposeAsync : IABetterClassDisposeAsync {
private Int32 _hasDisposedManaged;
private Int32 _hasDisposedNative;
private Int32 _hasSuppressedFinalize;
public Boolean HasDisposedManaged {
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
get => Interlocked.CompareExchange( ref this._hasDisposedManaged, 0, 0 ) == 1;
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
set {
if ( this.HasDisposedManaged ) {
return; //don't allow the setting to be changed once it has been set.
}
_ = Interlocked.Exchange( ref this._hasDisposedManaged, value ? 1 : 0 );
}
}
public Boolean HasDisposedNative {
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
get => Interlocked.CompareExchange( ref this._hasDisposedNative, 0, 0 ) == 1;
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
set {
if ( this.HasDisposedNative ) {
return; //don't allow the setting to be changed once it has been set.
}
_ = Interlocked.Exchange( ref this._hasDisposedNative, value ? 1 : 0 );
}
}
public Boolean HasSuppressedFinalize {
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
get => Interlocked.CompareExchange( ref this._hasSuppressedFinalize, 0, 0 ) == 1;
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
set {
if ( this.HasSuppressedFinalize ) {
return; //don't allow the setting to be changed once it has been set.
}
_ = Interlocked.Exchange( ref this._hasSuppressedFinalize, value ? 1 : 0 );
}
}
/// <summary>Can be changed to a property, if desired.</summary>
public Boolean IsDisposed => this.HasDisposedManaged && this.HasDisposedNative;
public async ValueTask DisposeAsync() {
if ( !this.HasDisposedManaged ) {
try {
await this.DisposeManagedAsync()
.ConfigureAwait( false ); //Any derived class should have overloaded this method and disposed of any managed objects inside.
}
catch ( Exception exception ) {
Debug.WriteLine( exception );
}
finally {
this.HasDisposedManaged = true;
}
}
if ( !this.HasDisposedNative ) {
try {
await this.DisposeNativeAsync().ConfigureAwait( false ); //Any derived class should overload this method.
}
catch ( Exception exception ) {
Debug.WriteLine( exception );
}
finally {
this.HasDisposedNative = true;
}
}
if ( this.IsDisposed && !this.HasSuppressedFinalize ) {
try {
GC.SuppressFinalize( this );
}
catch ( Exception exception ) {
Debug.WriteLine( exception );
}
finally {
this.HasSuppressedFinalize = true;
}
}
}
/// <summary>Override this method to dispose of any <see cref="IDisposable" /> managed fields or properties.</summary>
/// <code>using var bob = new DisposableType();</code>
[DebuggerStepThrough]
public virtual ValueTask DisposeManagedAsync() => ValueTask.CompletedTask;
/// <summary>
/// Dispose of COM objects, handles, etc in this method.
/// </summary>
[DebuggerStepThrough]
public virtual ValueTask DisposeNativeAsync() {
/*make this virtual so it is optional*/
this.HasDisposedNative = true;
return ValueTask.CompletedTask;
}
~ABetterClassDisposeAsync() {
this.DisposeAsync().AsTask().GetAwaiter().GetResult(); //TODO ugh, there has to be a better way.
}
/*
/// <summary>Set via <see cref="SetDisposeHint" /> to help find if an object has not been disposed of properly.</summary>
[CanBeNull]
private String? DisposeHint { get; set; }
*/
/*
/// <summary>Call at any time to set a debugging hint as to the creator of this disposable.</summary>
/// <param name="hint"></param>
[Conditional( "DEBUG" )]
public void SetDisposeHint( [CanBeNull] String? hint ) => this.DisposeHint = hint;
*/
}
}
// Copyright © Protiguous. All Rights Reserved.
//
// This entire copyright notice and license must be retained and must be kept visible in any binaries, libraries, repositories, or source code (directly or derived) from our binaries, libraries, projects, solutions, or applications.
//
// All source code belongs to Protiguous@Protiguous.com unless otherwise specified or the original license has been overwritten by formatting. (We try to avoid it from happening, but it does accidentally happen.)
//
// Any unmodified portions of source code gleaned from other sources still retain their original license and our thanks goes to those Authors.
// If you find your code unattributed in this source code, please let us know so we can properly attribute you and include the proper license and/or copyright(s).
// If you want to use any of our code in a commercial project, you must contact Protiguous@Protiguous.com for permission, license, and a quote.
//
// Donations, payments, and royalties are accepted via bitcoin: 1Mad8TxTqxKnMiHuZxArFvX8BuFEB9nqX2 and PayPal: Protiguous@Protiguous.com
//
// ====================================================================
// Disclaimer: Usage of the source code or binaries is AS-IS.
// No warranties are expressed, implied, or given.
// We are NOT responsible for Anything You Do With Our Code.
// We are NOT responsible for Anything You Do With Our Executables.
// We are NOT responsible for Anything You Do With Your Computer.
// ====================================================================
//
// Contact us by email if you have any questions, helpful criticism, or if you would like to use our code in your project(s).
// For business inquiries, please contact me at Protiguous@Protiguous.com.
// Our software can be found at "https://Protiguous.Software/"
// Our GitHub address is "https://github.com/Protiguous".
//
// File "ABetterClassDisposeReactive.cs" last touched on 2021-09-11 at 3:30 AM by Protiguous.
namespace Librainian.Utilities.Disposables {
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;
using ReactiveUI;
/// <summary>
/// <para>A class for easier implementation the proper <see cref="IDisposable" /> pattern.</para>
/// <para>Implement overrides on <see cref="DisposeManaged" />, and <see cref="DisposeNative" /> as needed.</para>
/// <code></code>
/// </summary>
/// <remarks>ABCD (hehe).</remarks>
/// <copyright>Created by Protiguous.</copyright>
public abstract class ABetterClassDisposeReactive : ReactiveObject, IABetterClassDispose {
private Int32 _hasDisposedManaged;
private Int32 _hasDisposedNative;
private Int32 _hasSuppressedFinalize;
public Boolean HasDisposedManaged {
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
get => Interlocked.CompareExchange( ref this._hasDisposedManaged, 0, 0 ) == 1;
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
set {
if ( this.HasDisposedManaged ) {
return; //don't allow the setting to be changed once it has been set.
}
_ = Interlocked.Exchange( ref this._hasDisposedManaged, value ? 1 : 0 );
}
}
public Boolean HasDisposedNative {
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
get => Interlocked.CompareExchange( ref this._hasDisposedNative, 0, 0 ) == 1;
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
set {
if ( this.HasDisposedNative ) {
return; //don't allow the setting to be changed once it has been set.
}
_ = Interlocked.Exchange( ref this._hasDisposedNative, value ? 1 : 0 );
}
}
public Boolean HasSuppressedFinalize {
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
get => Interlocked.CompareExchange( ref this._hasSuppressedFinalize, 0, 0 ) == 1;
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
set {
if ( this.HasSuppressedFinalize ) {
return; //don't allow the setting to be changed once it has been set.
}
_ = Interlocked.Exchange( ref this._hasSuppressedFinalize, value ? 1 : 0 );
}
}
/// <summary>Can be changed to a property, if desired.</summary>
public Boolean IsDisposed => this.HasDisposedManaged && this.HasDisposedNative;
/// <summary>
/// <para>
/// Disposes of managed resources, then unmanaged resources, and then calls <see cref="GC.SuppressFinalize" /> for
/// this object.
/// </para>
/// <para>Note: Calling <see cref="Dispose()" /> multiple times has no effect beyond the first call.</para>
/// </summary>
[DebuggerStepThrough]
public void Dispose() {
if ( !this.HasDisposedManaged ) {
try {
this.DisposeManaged(); //Any derived class should have overloaded this method and disposed of any managed objects inside.
}
catch ( Exception exception ) {
Debug.WriteLine( exception );
}
finally {
this.HasDisposedManaged = true;
}
}
if ( !this.HasDisposedNative ) {
try {
this.DisposeNative(); //Any derived class should overload this method.
}
catch ( Exception exception ) {
Debug.WriteLine( exception );
}
finally {
this.HasDisposedNative = true;
}
}
if ( this.IsDisposed && !this.HasSuppressedFinalize ) {
try {
GC.SuppressFinalize( this );
}
catch ( Exception exception ) {
Debug.WriteLine( exception );
}
finally {
this.HasSuppressedFinalize = true;
}
}
}
/// <summary>
/// Just calls <see cref="Dispose()" />. The parameter <paramref name="dispose" /> has no effect with this design.
/// </summary>
/// <param name="dispose"></param>
[DebuggerStepThrough]
public void Dispose( Boolean dispose ) => this.Dispose();
/// <summary>Override this method to dispose of any <see cref="IDisposable" /> managed fields or properties.</summary>
/// <example>
/// <code>using var bob = new DisposableType();</code>
/// </example>
[DebuggerStepThrough]
public virtual void DisposeManaged() { }
/// <summary>
/// Dispose of COM objects, handles, etc in this method.
/// </summary>
[DebuggerStepThrough]
public virtual void DisposeNative() =>
/*make this virtual so it is optional*/
this.HasDisposedNative = true;
~ABetterClassDisposeReactive() {
this.Dispose();
}
/*
/// <summary>Set via <see cref="SetDisposeHint" /> to help find if an object has not been disposed of properly.</summary>
[CanBeNull]
private String? DisposeHint { get; set; }
*/
/*
/// <summary>Call at any time to set a debugging hint as to the creator of this disposable.</summary>
/// <param name="hint"></param>
[Conditional( "DEBUG" )]
public void SetDisposeHint( [CanBeNull] String? hint ) => this.DisposeHint = hint;
*/
}
}
// Copyright © Protiguous. All Rights Reserved.
//
// This entire copyright notice and license must be retained and must be kept visible in any binaries, libraries, repositories, or source code (directly or derived) from our binaries, libraries, projects, solutions, or applications.
//
// All source code belongs to Protiguous@Protiguous.com unless otherwise specified or the original license has been overwritten by formatting. (We try to avoid it from happening, but it does accidentally happen.)
//
// Any unmodified portions of source code gleaned from other sources still retain their original license and our thanks goes to those Authors.
// If you find your code unattributed in this source code, please let us know so we can properly attribute you and include the proper license and/or copyright(s).
// If you want to use any of our code in a commercial project, you must contact Protiguous@Protiguous.com for permission, license, and a quote.
//
// Donations, payments, and royalties are accepted via bitcoin: 1Mad8TxTqxKnMiHuZxArFvX8BuFEB9nqX2 and PayPal: Protiguous@Protiguous.com
//
// ====================================================================
// Disclaimer: Usage of the source code or binaries is AS-IS.
// No warranties are expressed, implied, or given.
// We are NOT responsible for Anything You Do With Our Code.
// We are NOT responsible for Anything You Do With Our Executables.
// We are NOT responsible for Anything You Do With Your Computer.
// ====================================================================
//
// Contact us by email if you have any questions, helpful criticism, or if you would like to use our code in your project(s).
// For business inquiries, please contact me at Protiguous@Protiguous.com.
// Our software can be found at "https://Protiguous.Software/"
// Our GitHub address is "https://github.com/Protiguous".
//
// File "ABetterRecordDispose.cs" last touched on 2021-09-11 at 3:31 AM by Protiguous.
#nullable enable
namespace Librainian.Utilities.Disposables {
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;
/// <summary>
/// <para>A record for easier implementation the proper <see cref="IDisposable" /> pattern.</para>
/// <para>Implement overrides on <see cref="DisposeManaged" />, and <see cref="DisposeNative" /> as needed.</para>
/// <code></code>
/// </summary>
/// <remarks>ABRD.</remarks>
/// <remarks>This is purely experimental. I've just started learning records.</remarks>
/// <copyright>Created by Protiguous.</copyright>
public abstract record ABetterRecordDispose : IABetterClassDispose {
private Int32 _hasDisposedManaged;
private Int32 _hasDisposedNative;
private Int32 _hasSuppressedFinalize;
public Boolean HasDisposedManaged {
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
get => Interlocked.CompareExchange( ref this._hasDisposedManaged, 0, 0 ) == 1;
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
set {
if ( this.HasDisposedManaged ) {
return; //don't allow the setting to be changed once it has been set.
}
Interlocked.Exchange( ref this._hasDisposedManaged, value ? 1 : 0 );
}
}
public Boolean HasDisposedNative {
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
get => Interlocked.CompareExchange( ref this._hasDisposedNative, 0, 0 ) == 1;
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
set {
if ( this.HasDisposedNative ) {
return; //don't allow the setting to be changed once it has been set.
}
Interlocked.Exchange( ref this._hasDisposedNative, value ? 1 : 0 );
}
}
public Boolean HasSuppressedFinalize {
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
get => Interlocked.CompareExchange( ref this._hasSuppressedFinalize, 0, 0 ) == 1;
[MethodImpl( MethodImplOptions.AggressiveInlining )]
[DebuggerStepThrough]
set {
if ( this.HasSuppressedFinalize ) {
return; //don't allow the setting to be changed once it has been set.
}
Interlocked.Exchange( ref this._hasSuppressedFinalize, value ? 1 : 0 );
}
}
/// <summary>Can be changed to a property, if desired.</summary>
public Boolean IsDisposed => this.HasDisposedManaged && this.HasDisposedNative;
/// <summary>
/// <para>
/// Disposes of managed resources, then unmanaged resources, and then calls <see cref="GC.SuppressFinalize" /> for
/// this object.
/// </para>
/// <para>Note: Calling <see cref="Dispose()" /> multiple times has no effect beyond the first call.</para>
/// </summary>
[DebuggerStepThrough]
public void Dispose() {
if ( !this.HasDisposedManaged ) {
try {
this.DisposeManaged(); //Any derived class should have overloaded this method and disposed of any managed objects inside.
}
catch ( Exception exception ) {
Debug.WriteLine( exception );
}
finally {
this.HasDisposedManaged = true;
}
}
if ( !this.HasDisposedNative ) {
try {
this.DisposeNative(); //Any derived class should overload this method.
}
catch ( Exception exception ) {
Debug.WriteLine( exception );
}
finally {
this.HasDisposedNative = true;
}
}
if ( this.IsDisposed && !this.HasSuppressedFinalize ) {
try {
GC.SuppressFinalize( this );
}
catch ( Exception exception ) {
Debug.WriteLine( exception );
}
finally {
this.HasSuppressedFinalize = true;
}
}
}
/// <summary>
/// Just calls <see cref="Dispose()" />. The parameter <paramref name="dispose" /> has no effect with this design.
/// </summary>
/// <param name="dispose"></param>
[DebuggerStepThrough]
// ReSharper disable once UnusedParameter.Global
#pragma warning disable IDE0060 // Remove unused parameter
public void Dispose( Boolean dispose ) => this.Dispose();
#pragma warning restore IDE0060 // Remove unused parameter
/// <summary>Override this method to dispose of any <see cref="IDisposable" /> managed fields or properties.</summary>
/// <example>
/// <code>using var bob = new DisposableType();</code>
/// </example>
[DebuggerStepThrough]
public virtual void DisposeManaged() { }
/// <summary>
/// Dispose of COM objects, handles, etc in this method.
/// </summary>
[DebuggerStepThrough]
public virtual void DisposeNative() =>
/*make this virtual so it is optional*/
this.HasDisposedNative = true;
~ABetterRecordDispose() {
this.Dispose();
}
/*
/// <summary>Set via <see cref="SetDisposeHint" /> to help find if an object has not been disposed of properly.</summary>
[CanBeNull]
private String? DisposeHint { get; set; }
*/
/*
/// <summary>Call at any time to set a debugging hint as to the creator of this disposable.</summary>
/// <param name="hint"></param>
[Conditional( "DEBUG" )]
public void SetDisposeHint( [CanBeNull] String? hint ) => this.DisposeHint = hint;
*/
}
}
// Copyright © Protiguous. All Rights Reserved.
//
// This entire copyright notice and license must be retained and must be kept visible in any binaries, libraries, repositories, or source code (directly or derived) from our binaries, libraries, projects, solutions, or applications.
//
// All source code belongs to Protiguous@Protiguous.com unless otherwise specified or the original license has been overwritten by formatting. (We try to avoid it from happening, but it does accidentally happen.)
//
// Any unmodified portions of source code gleaned from other sources still retain their original license and our thanks goes to those Authors.
// If you find your code unattributed in this source code, please let us know so we can properly attribute you and include the proper license and/or copyright(s).
//
// If you want to use any of our code in a commercial project, you must contact Protiguous@Protiguous.com for permission, license, and a quote.
//
// Donations, payments, and royalties are accepted via bitcoin:1Mad8TxTqxKnMiHuZxArFvX8BuFEB9nqX2 and PayPal:Protiguous@Protiguous.com
//
// ====================================================================
// Disclaimer: Usage of the source code or binaries is AS-IS.
// No warranties are expressed, implied, or given.
// We are NOT responsible for Anything You Do With Our Code.
// We are NOT responsible for Anything You Do With Our Executables.
// We are NOT responsible for Anything You Do With Your Computer.
// ====================================================================
//
// Contact us by email if you have any questions, helpful criticism, or if you would like to use our code in your project(s).
// For business inquiries, please contact me at Protiguous@Protiguous.com.
//
// Our software can be found at "https://Protiguous.Software/"
// Our GitHub address is "https://github.com/Protiguous".
//
// File "ExampleUsingABetterClassDispose.cs" last formatted on 2020-11-07.
#nullable enable
namespace Librainian.Tests {
using System;
using System.IO;
using Utilities;
public class ExampleUsingABetterClassDispose : ABetterClassDispose {
private MemoryStream? _memoryStream = new MemoryStream();
private SysComObject? _sysComObject = new SysComObject();
public ExampleUsingABetterClassDispose() => this._sysComObject?.ReserveMemory();
public override void DisposeManaged() {
using ( this._memoryStream ) {
this._memoryStream = null;
}
base.DisposeManaged();
}
public override void DisposeNative() {
this._sysComObject?.ReleaseMemory();
this._sysComObject = null;
base.DisposeNative();
}
}
/// <summary>
/// A fake COM interface object.
/// </summary>
public class SysComObject {
public void ReleaseMemory() {
throw new NotImplementedException( "Not actual code." );
}
public void ReserveMemory() {
throw new NotImplementedException( "Not actual code." );
}
}
}
// Copyright © Protiguous. All Rights Reserved.
//
// This entire copyright notice and license must be retained and must be kept visible in any binaries, libraries, repositories, or source code (directly or derived) from our binaries, libraries, projects, solutions, or applications.
//
// All source code belongs to Protiguous@Protiguous.com unless otherwise specified or the original license has been overwritten by formatting. (We try to avoid it from happening, but it does accidentally happen.)
//
// Any unmodified portions of source code gleaned from other sources still retain their original license and our thanks goes to those Authors.
// If you find your code unattributed in this source code, please let us know so we can properly attribute you and include the proper license and/or copyright(s).
// If you want to use any of our code in a commercial project, you must contact Protiguous@Protiguous.com for permission, license, and a quote.
//
// Donations, payments, and royalties are accepted via bitcoin: 1Mad8TxTqxKnMiHuZxArFvX8BuFEB9nqX2 and PayPal: Protiguous@Protiguous.com
//
// ====================================================================
// Disclaimer: Usage of the source code or binaries is AS-IS.
// No warranties are expressed, implied, or given.
// We are NOT responsible for Anything You Do With Our Code.
// We are NOT responsible for Anything You Do With Our Executables.
// We are NOT responsible for Anything You Do With Your Computer.
// ====================================================================
//
// Contact us by email if you have any questions, helpful criticism, or if you would like to use our code in your project(s).
// For business inquiries, please contact me at Protiguous@Protiguous.com.
// Our software can be found at "https://Protiguous.Software/"
// Our GitHub address is "https://github.com/Protiguous".
//
// File "IABetterClassDispose.cs" last touched on 2021-09-11 at 3:32 AM by Protiguous.
namespace Librainian.Utilities.Disposables {
using System;
using System.Diagnostics.CodeAnalysis;
public interface IABetterClassDispose : IDisposable {
Boolean HasDisposedManaged { get; set; }
Boolean HasDisposedNative { get; set; }
Boolean HasSuppressedFinalize { get; set; }
Boolean IsDisposed { get; }
[SuppressMessage( "ReSharper", "UnusedParameter.Global" )]
void Dispose( Boolean dispose );
void DisposeManaged();
void DisposeNative();
}
}
// Copyright © Protiguous. All Rights Reserved.
//
// This entire copyright notice and license must be retained and must be kept visible in any binaries, libraries, repositories, or source code (directly or derived) from our binaries, libraries, projects, solutions, or applications.
//
// All source code belongs to Protiguous@Protiguous.com unless otherwise specified or the original license has been overwritten by formatting. (We try to avoid it from happening, but it does accidentally happen.)
//
// Any unmodified portions of source code gleaned from other sources still retain their original license and our thanks goes to those Authors.
// If you find your code unattributed in this source code, please let us know so we can properly attribute you and include the proper license and/or copyright(s).
// If you want to use any of our code in a commercial project, you must contact Protiguous@Protiguous.com for permission, license, and a quote.
//
// Donations, payments, and royalties are accepted via bitcoin: 1Mad8TxTqxKnMiHuZxArFvX8BuFEB9nqX2 and PayPal: Protiguous@Protiguous.com
//
// ====================================================================
// Disclaimer: Usage of the source code or binaries is AS-IS.
// No warranties are expressed, implied, or given.
// We are NOT responsible for Anything You Do With Our Code.
// We are NOT responsible for Anything You Do With Our Executables.
// We are NOT responsible for Anything You Do With Your Computer.
// ====================================================================
//
// Contact us by email if you have any questions, helpful criticism, or if you would like to use our code in your project(s).
// For business inquiries, please contact me at Protiguous@Protiguous.com.
// Our software can be found at "https://Protiguous.Software/"
// Our GitHub address is "https://github.com/Protiguous".
//
// File "IABetterClassDisposeAsync.cs" last touched on 2021-09-11 at 3:32 AM by Protiguous.
namespace Librainian.Utilities.Disposables {
using System;
using System.Threading.Tasks;
public interface IABetterClassDisposeAsync : IAsyncDisposable {
Boolean HasDisposedManaged { get; set; }
Boolean HasDisposedNative { get; set; }
Boolean HasSuppressedFinalize { get; set; }
Boolean IsDisposed { get; }
ValueTask DisposeManagedAsync();
ValueTask DisposeNativeAsync();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment