<PackageReference Include="System.Reactive" Version="6.0.1-preview.1" />

StableCompositeDisposable

Represents a group of disposable resources that are disposed together.
using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Threading; namespace System.Reactive.Disposables { public abstract class StableCompositeDisposable : ICancelable, IDisposable { private sealed class Binary : StableCompositeDisposable { private SingleAssignmentDisposableValue _disposable1; private SingleAssignmentDisposableValue _disposable2; public override bool IsDisposed => _disposable1.IsDisposed; [System.Runtime.CompilerServices.NullableContext(1)] public Binary(IDisposable disposable1, IDisposable disposable2) { _disposable1.Disposable = disposable1; _disposable2.Disposable = disposable2; } public override void Dispose() { _disposable1.Dispose(); _disposable2.Dispose(); } } private sealed class NAryEnumerable : StableCompositeDisposable { [System.Runtime.CompilerServices.Nullable(new byte[] { 2, 1 })] private volatile List<IDisposable> _disposables; public override bool IsDisposed => _disposables == null; [System.Runtime.CompilerServices.NullableContext(1)] public NAryEnumerable(IEnumerable<IDisposable> disposables) { _disposables = new List<IDisposable>(disposables); if (_disposables.Contains(null)) throw new ArgumentException(Strings_Core.DISPOSABLES_CANT_CONTAIN_NULL, "disposables"); } public override void Dispose() { List<IDisposable> list = Interlocked.Exchange(ref _disposables, null); if (list != null) { foreach (IDisposable item in list) { item.Dispose(); } } } } private sealed class NAryArray : StableCompositeDisposable { [System.Runtime.CompilerServices.Nullable(new byte[] { 2, 1 })] private IDisposable[] _disposables; public override bool IsDisposed => Volatile.Read(ref _disposables) == null; [System.Runtime.CompilerServices.NullableContext(1)] public NAryArray(IDisposable[] disposables) { if (Array.IndexOf(disposables, null) != -1) throw new ArgumentException(Strings_Core.DISPOSABLES_CANT_CONTAIN_NULL, "disposables"); int num = disposables.Length; IDisposable[] array = new IDisposable[num]; Array.Copy(disposables, 0, array, 0, num); Volatile.Write(ref _disposables, array); } public override void Dispose() { IDisposable[] array = Interlocked.Exchange(ref _disposables, null); if (array != null) { IDisposable[] array2 = array; for (int i = 0; i < array2.Length; i++) { array2[i].Dispose(); } } } } private sealed class NAryTrustedArray : StableCompositeDisposable { [System.Runtime.CompilerServices.Nullable(new byte[] { 2, 1 })] private IDisposable[] _disposables; public override bool IsDisposed => Volatile.Read(ref _disposables) == null; [System.Runtime.CompilerServices.NullableContext(1)] public NAryTrustedArray(IDisposable[] disposables) { Volatile.Write(ref _disposables, disposables); } public override void Dispose() { IDisposable[] array = Interlocked.Exchange(ref _disposables, null); if (array != null) { IDisposable[] array2 = array; for (int i = 0; i < array2.Length; i++) { array2[i].Dispose(); } } } } public abstract bool IsDisposed { get; } [System.Runtime.CompilerServices.NullableContext(1)] public static ICancelable Create(IDisposable disposable1, IDisposable disposable2) { if (disposable1 == null) throw new ArgumentNullException("disposable1"); if (disposable2 == null) throw new ArgumentNullException("disposable2"); return new Binary(disposable1, disposable2); } [System.Runtime.CompilerServices.NullableContext(1)] public static ICancelable Create(params IDisposable[] disposables) { if (disposables == null) throw new ArgumentNullException("disposables"); return new NAryArray(disposables); } [System.Runtime.CompilerServices.NullableContext(1)] internal static ICancelable CreateTrusted(params IDisposable[] disposables) { return new NAryTrustedArray(disposables); } [System.Runtime.CompilerServices.NullableContext(1)] public static ICancelable Create(IEnumerable<IDisposable> disposables) { if (disposables == null) throw new ArgumentNullException("disposables"); return new NAryEnumerable(disposables); } public abstract void Dispose(); } }