| | | 1 | | using System; |
| | | 2 | | using System.Threading; |
| | | 3 | | |
| | | 4 | | namespace SwiftCollections; |
| | | 5 | | |
| | | 6 | | /// <summary> |
| | | 7 | | /// A lazily initialized disposable object. |
| | | 8 | | /// This class extends <see cref="Lazy{T}"/> to support <see cref="IDisposable"/> objects, |
| | | 9 | | /// ensuring proper resource cleanup when disposed. |
| | | 10 | | /// </summary> |
| | | 11 | | /// <typeparam name="T">The type of the lazily initialized object, which must implement <see cref="IDisposable"/>.</type |
| | | 12 | | public class SwiftLazyDisposable<T> : Lazy<T>, IDisposable where T : IDisposable |
| | | 13 | | { |
| | | 14 | | #region Fields |
| | | 15 | | |
| | | 16 | | /// <summary> |
| | | 17 | | /// Indicates whether the lazy instance has been disposed. |
| | | 18 | | /// Prevents multiple disposal attempts, ensuring safe resource cleanup. |
| | | 19 | | /// </summary> |
| | | 20 | | private volatile bool _disposed; |
| | | 21 | | |
| | | 22 | | #endregion |
| | | 23 | | |
| | | 24 | | #region Constructors |
| | | 25 | | |
| | | 26 | | /// <summary> |
| | | 27 | | /// Initializes a new instance of the <see cref="SwiftLazyDisposable{T}"/> class. |
| | | 28 | | /// When lazy initialization occurs, the default constructor is used. |
| | | 29 | | /// </summary> |
| | 3 | 30 | | public SwiftLazyDisposable() : base() { } |
| | | 31 | | |
| | | 32 | | /// <summary> |
| | | 33 | | /// Initializes a new instance of the <see cref="SwiftLazyDisposable{T}"/> class. |
| | | 34 | | /// When lazy initialization occurs, the default constructor of the target type |
| | | 35 | | /// and the specified initialization mode are used. |
| | | 36 | | /// </summary> |
| | | 37 | | /// <param name="isThreadSafe"> |
| | | 38 | | /// true to make this instance usable concurrently by multiple threads; |
| | | 39 | | /// false to make the instance usable by only one thread at a time. |
| | | 40 | | /// </param> |
| | 3 | 41 | | public SwiftLazyDisposable(bool isThreadSafe) : base(isThreadSafe) { } |
| | | 42 | | |
| | | 43 | | /// <summary> |
| | | 44 | | /// Initializes a new instance of the <see cref="SwiftLazyDisposable{T}"/> class |
| | | 45 | | /// that uses the default constructor of T and the specified thread-safety mode. |
| | | 46 | | /// </summary> |
| | | 47 | | /// <param name="mode"> |
| | | 48 | | /// One of the enumeration values that specifies the thread safety mode. |
| | | 49 | | /// </param> |
| | 3 | 50 | | public SwiftLazyDisposable(LazyThreadSafetyMode mode) : base(mode) { } |
| | | 51 | | |
| | | 52 | | /// <summary> |
| | | 53 | | /// Initializes a new instance of the <see cref="SwiftLazyDisposable{T}"/> class. |
| | | 54 | | /// When lazy initialization occurs, the specified initialization function is used. |
| | | 55 | | /// </summary> |
| | | 56 | | /// <param name="valueFactory"> |
| | | 57 | | /// The delegate that is invoked to produce the lazily initialized value when it is needed. |
| | | 58 | | /// </param> |
| | 183 | 59 | | public SwiftLazyDisposable(Func<T> valueFactory) : base(valueFactory) { } |
| | | 60 | | |
| | | 61 | | /// <summary> |
| | | 62 | | /// Initializes a new instance of the <see cref="SwiftLazyDisposable{T}"/> class. |
| | | 63 | | /// When lazy initialization occurs, the specified initialization function |
| | | 64 | | /// and initialization mode are used. |
| | | 65 | | /// </summary> |
| | | 66 | | /// <param name="valueFactory"> |
| | | 67 | | /// The delegate that is invoked to produce the lazily initialized value when it is needed. |
| | | 68 | | /// </param> |
| | | 69 | | /// <param name="isThreadSafe"> |
| | | 70 | | /// true to make this instance usable concurrently by multiple threads; |
| | | 71 | | /// false to make this instance usable by only one thread at a time. |
| | | 72 | | /// </param> |
| | 3 | 73 | | public SwiftLazyDisposable(Func<T> valueFactory, bool isThreadSafe) : base(valueFactory, isThreadSafe) { } |
| | | 74 | | |
| | | 75 | | /// <summary> |
| | | 76 | | /// Initializes a new instance of the <see cref="SwiftLazyDisposable{T}"/> class |
| | | 77 | | /// using the specified initialization function and thread-safety mode. |
| | | 78 | | /// </summary> |
| | | 79 | | /// <param name="valueFactory"> |
| | | 80 | | /// The delegate that is invoked to produce the lazily initialized value when it is needed. |
| | | 81 | | /// </param> |
| | | 82 | | /// <param name="mode"> |
| | | 83 | | /// One of the enumeration values that specifies the thread safety mode. |
| | | 84 | | /// </param> |
| | 27 | 85 | | public SwiftLazyDisposable(Func<T> valueFactory, LazyThreadSafetyMode mode) : base(valueFactory, mode) { } |
| | | 86 | | |
| | | 87 | | #endregion |
| | | 88 | | |
| | | 89 | | #region Utility |
| | | 90 | | |
| | 3 | 91 | | public override string ToString() => IsValueCreated ? Value.ToString() : "LazyDisposable (Not Created)"; |
| | | 92 | | |
| | | 93 | | #endregion |
| | | 94 | | |
| | | 95 | | #region IDisposable Implementation |
| | | 96 | | |
| | | 97 | | /// <summary> |
| | | 98 | | /// Disposes the lazily initialized value if it has been created. |
| | | 99 | | /// Ensures that disposal is only performed once. |
| | | 100 | | /// </summary> |
| | | 101 | | public void Dispose() |
| | 57 | 102 | | { |
| | 57 | 103 | | if (_disposed || !this.IsValueCreated) |
| | 23 | 104 | | return; |
| | | 105 | | |
| | 34 | 106 | | _disposed = true; |
| | 34 | 107 | | this.Value.Dispose(); |
| | | 108 | | |
| | | 109 | | // Suppress finalization since we've manually disposed |
| | 34 | 110 | | GC.SuppressFinalize(this); |
| | 57 | 111 | | } |
| | | 112 | | |
| | | 113 | | /// <summary> |
| | | 114 | | /// Finalizer to ensure disposal if Dispose() is never called. |
| | | 115 | | /// </summary> |
| | 54 | 116 | | ~SwiftLazyDisposable() => Dispose(); |
| | | 117 | | |
| | | 118 | | #endregion |
| | | 119 | | } |