💬

ObservableCollectionの購読をDisposableにする

2022/10/24に公開

メモ

ReactivePropertyなんかで、Disposeで購読を解除できるのがいいなあと思ったので。

とりあえずonNextを引数にとるものだけ。
クラス名とかはもうちょっと考えた方がいいですね。

using System.Collections.ObjectModel;
using System.Collections.Specialized;

namespace Utilities.Extensions
{
    public static class ObservableCollectionSubscription_
    {
        public static IDisposable Subscribe<T>(this ObservableCollection<T> inDistoributor, Action<NotifyCollectionChangedEventArgs> onNext)
            => new ObservableCollectionSubscription<T>(inDistoributor, onNext);
    }

    internal class ObservableCollectionSubscription<T> : IDisposable
    {
        public ObservableCollectionSubscription(ObservableCollection<T> inDistoributor, Action<NotifyCollectionChangedEventArgs> onNext)
        {
            _distributor = inDistoributor;
            _distributor.CollectionChanged += _distributor_CollectionChanged;

            _onNext = onNext;
        }

        public void Dispose()
        {
            Dispose(disposing: true);
            GC.SuppressFinalize(this);
        }

        private void _distributor_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
            => _onNext(e);

        private readonly ObservableCollection<T> _distributor;
        private readonly Action<NotifyCollectionChangedEventArgs> _onNext;
        private bool _isDisposed;

        protected virtual void Dispose(bool disposing)
        {
            if (!_isDisposed)
            {
                if (disposing)
                    _distributor.CollectionChanged -= _distributor_CollectionChanged;

                _isDisposed = true;
            }
        }
    }
}

Discussion