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();
    }
}