Ver Fonte

Merge pull request #397 from Reactive-Extensions/CreateSink

Reduction of producer/sink overheads
Bart J.F. De Smet há 8 anos atrás
pai
commit
83710cfa93
99 ficheiros alterados com 1342 adições e 1959 exclusões
  1. 9 15
      Rx.NET/Source/src/System.Reactive/Concurrency/Synchronization.ObserveOn.cs
  2. 5 8
      Rx.NET/Source/src/System.Reactive/Concurrency/Synchronization.Synchronize.cs
  3. 92 21
      Rx.NET/Source/src/System.Reactive/Internal/Producer.cs
  4. 4 9
      Rx.NET/Source/src/System.Reactive/Linq/Observable/AddRef.cs
  5. 15 24
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Aggregate.cs
  6. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/All.cs
  7. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Amb.cs
  8. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Any.cs
  9. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/AsObservable.cs
  10. 50 80
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Average.cs
  11. 30 48
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Buffer.cs
  12. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Case.cs
  13. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Cast.cs
  14. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Catch.cs
  15. 71 113
      Rx.NET/Source/src/System.Reactive/Linq/Observable/CombineLatest.Generated.cs
  16. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/CombineLatest.Generated.tt
  17. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/CombineLatest.cs
  18. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Concat.cs
  19. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Contains.cs
  20. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Count.cs
  21. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/DefaultIfEmpty.cs
  22. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Defer.cs
  23. 85 84
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Delay.cs
  24. 8 14
      Rx.NET/Source/src/System.Reactive/Linq/Observable/DelaySubscription.cs
  25. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Dematerialize.cs
  26. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Distinct.cs
  27. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/DistinctUntilChanged.cs
  28. 15 24
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Do.cs
  29. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/DoWhile.cs
  30. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/ElementAt.cs
  31. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/ElementAtOrDefault.cs
  32. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Empty.cs
  33. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Finally.cs
  34. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/FirstAsync.cs
  35. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/FirstOrDefaultAsync.cs
  36. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/For.cs
  37. 2 2
      Rx.NET/Source/src/System.Reactive/Linq/Observable/FromEvent.cs
  38. 15 24
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Generate.cs
  39. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/GroupBy.cs
  40. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/GroupByUntil.cs
  41. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/GroupJoin.cs
  42. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/If.cs
  43. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/IgnoreElements.cs
  44. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/IsEmpty.cs
  45. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Join.cs
  46. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/LastAsync.cs
  47. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/LastOrDefaultAsync.cs
  48. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/LongCount.cs
  49. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Materialize.cs
  50. 75 109
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Max.cs
  51. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/MaxBy.cs
  52. 15 24
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Merge.cs
  53. 75 109
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Min.cs
  54. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/MinBy.cs
  55. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Multicast.cs
  56. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/OfType.cs
  57. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/OnErrorResumeNext.cs
  58. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Range.cs
  59. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/RefCount.cs
  60. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Repeat.cs
  61. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Return.cs
  62. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Sample.cs
  63. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Scan.cs
  64. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Select.cs
  65. 64 110
      Rx.NET/Source/src/System.Reactive/Linq/Observable/SelectMany.cs
  66. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/SequenceEqual.cs
  67. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/SingleAsync.cs
  68. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/SingleOrDefaultAsync.cs
  69. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Skip.cs
  70. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/SkipLast.cs
  71. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/SkipUntil.cs
  72. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/SkipWhile.cs
  73. 50 80
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Sum.cs
  74. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Switch.cs
  75. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Synchronize.cs
  76. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Take.cs
  77. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/TakeLast.cs
  78. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/TakeLastBuffer.cs
  79. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/TakeUntil.cs
  80. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/TakeWhile.cs
  81. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Throttle.cs
  82. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Throw.cs
  83. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/TimeInterval.cs
  84. 15 24
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Timeout.cs
  85. 16 28
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Timer.cs
  86. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Timestamp.cs
  87. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/ToArray.cs
  88. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/ToDictionary.cs
  89. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/ToList.cs
  90. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/ToLookup.cs
  91. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/ToObservable.cs
  92. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Using.cs
  93. 10 16
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Where.cs
  94. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/While.cs
  95. 30 48
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Window.cs
  96. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/WithLatestFrom.cs
  97. 71 113
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Zip.Generated.cs
  98. 5 8
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Zip.Generated.tt
  99. 15 24
      Rx.NET/Source/src/System.Reactive/Linq/Observable/Zip.cs

+ 9 - 15
Rx.NET/Source/src/System.Reactive/Concurrency/Synchronization.ObserveOn.cs

@@ -9,7 +9,7 @@ namespace System.Reactive.Concurrency
 {
     internal static class ObserveOn<TSource>
     {
-        internal sealed class Scheduler : Producer<TSource>
+        internal sealed class Scheduler : Producer<TSource, ObserveOnObserver<TSource>>
         {
             private readonly IObservable<TSource> _source;
             private readonly IScheduler _scheduler;
@@ -20,16 +20,13 @@ namespace System.Reactive.Concurrency
                 _scheduler = scheduler;
             }
 
+            protected override ObserveOnObserver<TSource> CreateSink(IObserver<TSource> observer, IDisposable cancel) => new ObserveOnObserver<TSource>(_scheduler, observer, cancel);
+
             [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "2", Justification = "Visibility restricted to friend assemblies. Those should be correct by inspection.")]
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new ObserveOnObserver<TSource>(_scheduler, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override IDisposable Run(ObserveOnObserver<TSource> sink) => _source.SubscribeSafe(sink);
         }
 
-        internal sealed class Context : Producer<TSource>
+        internal sealed class Context : Producer<TSource, Context._>
         {
             private readonly IObservable<TSource> _source;
             private readonly SynchronizationContext _context;
@@ -40,15 +37,12 @@ namespace System.Reactive.Concurrency
                 _context = context;
             }
 
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_context, observer, cancel);
+
             [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "2", Justification = "Visibility restricted to friend assemblies. Those should be correct by inspection.")]
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_context, observer, cancel);
-                setSink(sink);
-                return sink.Run(_source);
-            }
+            protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private readonly SynchronizationContext _context;
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Concurrency/Synchronization.Synchronize.cs

@@ -4,7 +4,7 @@
 
 namespace System.Reactive.Concurrency
 {
-    internal sealed class Synchronize<TSource> : Producer<TSource>
+    internal sealed class Synchronize<TSource> : Producer<TSource, Synchronize<TSource>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly object _gate;
@@ -20,15 +20,12 @@ namespace System.Reactive.Concurrency
             _source = source;
         }
 
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(this, observer, cancel);
+
         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "2", Justification = "Visibility restricted to friend assemblies. Those should be correct by inspection.")]
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(this, observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             private readonly Synchronize<TSource> _parent;
             private readonly object _gate;

+ 92 - 21
Rx.NET/Source/src/System.Reactive/Internal/Producer.cs

@@ -4,6 +4,7 @@
 
 using System.Reactive.Concurrency;
 using System.Reactive.Disposables;
+using System.Threading;
 
 namespace System.Reactive
 {
@@ -20,7 +21,7 @@ namespace System.Reactive
     /// Base class for implementation of query operators, providing performance benefits over the use of Observable.Create.
     /// </summary>
     /// <typeparam name="TSource">Type of the resulting sequence's elements.</typeparam>
-    internal abstract class Producer<TSource> : IProducer<TSource>
+    internal abstract class BasicProducer<TSource> : IProducer<TSource>
     {
         /// <summary>
         /// Publicly visible Subscribe method.
@@ -32,17 +33,12 @@ namespace System.Reactive
             if (observer == null)
                 throw new ArgumentNullException(nameof(observer));
 
-            return SubscribeRaw(observer, true);
+            return SubscribeRaw(observer, enableSafeguard: true);
         }
 
         public IDisposable SubscribeRaw(IObserver<TSource> observer, bool enableSafeguard)
         {
-            var state = new State();
-            state.observer = observer;
-            state.sink = new SingleAssignmentDisposable();
-            state.subscription = new SingleAssignmentDisposable();
-
-            var d = StableCompositeDisposable.Create(state.sink, state.subscription);
+            var subscription = new SingleAssignmentDisposable();
 
             //
             // See AutoDetachObserver.cs for more information on the safeguarding requirement and
@@ -50,36 +46,31 @@ namespace System.Reactive
             //
             if (enableSafeguard)
             {
-                state.observer = SafeObserver<TSource>.Create(state.observer, d);
+                observer = SafeObserver<TSource>.Create(observer, subscription);
             }
 
             if (CurrentThreadScheduler.IsScheduleRequired)
             {
+                var state = new State { subscription = subscription, observer = observer };
                 CurrentThreadScheduler.Instance.Schedule(state, Run);
             }
             else
             {
-                state.subscription.Disposable = Run(state.observer, state.subscription, state.Assign);
+                subscription.Disposable = Run(observer);
             }
 
-            return d;
+            return subscription;
         }
 
         private struct State
         {
-            public SingleAssignmentDisposable sink;
             public SingleAssignmentDisposable subscription;
             public IObserver<TSource> observer;
-
-            public void Assign(IDisposable s)
-            {
-                sink.Disposable = s;
-            }
         }
 
         private IDisposable Run(IScheduler _, State x)
         {
-            x.subscription.Disposable = Run(x.observer, x.subscription, x.Assign);
+            x.subscription.Disposable = Run(x.observer);
             return Disposable.Empty;
         }
 
@@ -87,10 +78,90 @@ namespace System.Reactive
         /// Core implementation of the query operator, called upon a new subscription to the producer object.
         /// </summary>
         /// <param name="observer">Observer to send notifications on. The implementation of a producer must ensure the correct message grammar on the observer.</param>
-        /// <param name="cancel">The subscription disposable object returned from the Run call, passed in such that it can be forwarded to the sink, allowing it to dispose the subscription upon sending a final message (or prematurely for other reasons).</param>
-        /// <param name="setSink">Callback to communicate the sink object to the subscriber, allowing consumers to tunnel a Dispose call into the sink, which can stop the processing.</param>
         /// <returns>Disposable representing all the resources and/or subscriptions the operator uses to process events.</returns>
         /// <remarks>The <paramref name="observer">observer</paramref> passed in to this method is not protected using auto-detach behavior upon an OnError or OnCompleted call. The implementation must ensure proper resource disposal and enforce the message grammar.</remarks>
-        protected abstract IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink);
+        protected abstract IDisposable Run(IObserver<TSource> observer);
+    }
+
+    internal abstract class Producer<TSource, TSink> : IProducer<TSource>
+        where TSink : IDisposable
+    {
+        /// <summary>
+        /// Publicly visible Subscribe method.
+        /// </summary>
+        /// <param name="observer">Observer to send notifications on. The implementation of a producer must ensure the correct message grammar on the observer.</param>
+        /// <returns>IDisposable to cancel the subscription. This causes the underlying sink to be notified of unsubscription, causing it to prevent further messages from being sent to the observer.</returns>
+        public IDisposable Subscribe(IObserver<TSource> observer)
+        {
+            if (observer == null)
+                throw new ArgumentNullException(nameof(observer));
+
+            return SubscribeRaw(observer, enableSafeguard: true);
+        }
+
+        public IDisposable SubscribeRaw(IObserver<TSource> observer, bool enableSafeguard)
+        {
+            var subscription = new SubscriptionDisposable();
+
+            //
+            // See AutoDetachObserver.cs for more information on the safeguarding requirement and
+            // its implementation aspects.
+            //
+            if (enableSafeguard)
+            {
+                observer = SafeObserver<TSource>.Create(observer, subscription);
+            }
+
+            var sink = CreateSink(observer, subscription.Inner);
+
+            subscription.Sink = sink;
+
+            if (CurrentThreadScheduler.IsScheduleRequired)
+            {
+                var state = new State { sink = sink, inner = subscription.Inner };
+
+                CurrentThreadScheduler.Instance.Schedule(state, Run);
+            }
+            else
+            {
+                subscription.Inner.Disposable = Run(sink);
+            }
+
+            return subscription;
+        }
+
+        private struct State
+        {
+            public TSink sink;
+            public SingleAssignmentDisposable inner;
+        }
+
+        private IDisposable Run(IScheduler _, State x)
+        {
+            x.inner.Disposable = Run(x.sink);
+            return Disposable.Empty;
+        }
+
+        /// <summary>
+        /// Core implementation of the query operator, called upon a new subscription to the producer object.
+        /// </summary>
+        /// <param name="sink">The sink object.</param>
+        protected abstract IDisposable Run(TSink sink);
+
+        protected abstract TSink CreateSink(IObserver<TSource> observer, IDisposable cancel);
+    }
+
+    internal sealed class SubscriptionDisposable : ICancelable
+    {
+        public volatile IDisposable Sink;
+        public readonly SingleAssignmentDisposable Inner = new SingleAssignmentDisposable();
+
+        public bool IsDisposed => Sink == null;
+
+        public void Dispose()
+        {
+            Interlocked.Exchange(ref Sink, null)?.Dispose();
+            Inner.Dispose();
+        }
     }
 }

+ 4 - 9
Rx.NET/Source/src/System.Reactive/Linq/Observable/AddRef.cs

@@ -6,7 +6,7 @@ using System.Reactive.Disposables;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal class AddRef<TSource> : Producer<TSource>
+    internal class AddRef<TSource> : Producer<TSource, AddRef<TSource>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly RefCountDisposable _refCount;
@@ -17,16 +17,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _refCount = refCount;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var d = StableCompositeDisposable.Create(_refCount.GetDisposable(), cancel);
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, StableCompositeDisposable.Create(_refCount.GetDisposable(), cancel));
 
-            var sink = new _(observer, d);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 15 - 24
Rx.NET/Source/src/System.Reactive/Linq/Observable/Aggregate.cs

@@ -4,7 +4,7 @@
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Aggregate<TSource> : Producer<TSource>
+    internal sealed class Aggregate<TSource> : Producer<TSource, Aggregate<TSource>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly Func<TSource, TSource, TSource> _accumulator;
@@ -15,14 +15,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _accumulator = accumulator;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_accumulator, observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_accumulator, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             private readonly Func<TSource, TSource, TSource> _accumulator;
             private TSource _accumulation;
@@ -80,7 +77,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class Aggregate<TSource, TAccumulate> : Producer<TAccumulate>
+    internal sealed class Aggregate<TSource, TAccumulate> : Producer<TAccumulate, Aggregate<TSource, TAccumulate>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly TAccumulate _seed;
@@ -93,14 +90,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _accumulator = accumulator;
         }
 
-        protected override IDisposable Run(IObserver<TAccumulate> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_seed, _accumulator, observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<TAccumulate> observer, IDisposable cancel) => new _(_seed, _accumulator, observer, cancel);
 
-        private sealed class _ : Sink<TAccumulate>, IObserver<TSource>
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
+
+        internal sealed class _ : Sink<TAccumulate>, IObserver<TSource>
         {
             private readonly Func<TAccumulate, TSource, TAccumulate> _accumulator;
             private TAccumulate _accumulation;
@@ -140,7 +134,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class Aggregate<TSource, TAccumulate, TResult> : Producer<TResult>
+    internal sealed class Aggregate<TSource, TAccumulate, TResult> : Producer<TResult, Aggregate<TSource, TAccumulate, TResult>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly TAccumulate _seed;
@@ -155,14 +149,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(this, observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<TResult>, IObserver<TSource>
+        internal sealed class _ : Sink<TResult>, IObserver<TSource>
         {
             private readonly Func<TAccumulate, TSource, TAccumulate> _accumulator;
             private readonly Func<TAccumulate, TResult> _resultSelector;

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/All.cs

@@ -4,7 +4,7 @@
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class All<TSource> : Producer<bool>
+    internal sealed class All<TSource> : Producer<bool, All<TSource>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly Func<TSource, bool> _predicate;
@@ -15,14 +15,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _predicate = predicate;
         }
 
-        protected override IDisposable Run(IObserver<bool> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_predicate, observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<bool> observer, IDisposable cancel) => new _(_predicate, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<bool>, IObserver<TSource>
+        internal sealed class _ : Sink<bool>, IObserver<TSource>
         {
             private readonly Func<TSource, bool> _predicate;
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Amb.cs

@@ -6,7 +6,7 @@ using System.Reactive.Disposables;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Amb<TSource> : Producer<TSource>
+    internal sealed class Amb<TSource> : Producer<TSource, Amb<TSource>._>
     {
         private readonly IObservable<TSource> _left;
         private readonly IObservable<TSource> _right;
@@ -17,14 +17,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _right = right;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _( observer, cancel);
-            setSink(sink);
-            return sink.Run(this);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        private sealed class _ : Sink<TSource>
+        internal sealed class _ : Sink<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/Any.cs

@@ -6,7 +6,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class Any<TSource>
     {
-        internal sealed class Count : Producer<bool>
+        internal sealed class Count : Producer<bool, Count._>
         {
             private readonly IObservable<TSource> _source;
 
@@ -15,14 +15,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _source = source;
             }
 
-            protected override IDisposable Run(IObserver<bool> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<bool> observer, IDisposable cancel) => new _(observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<bool>, IObserver<TSource>
+            internal sealed class _ : Sink<bool>, IObserver<TSource>
             {
                 public _(IObserver<bool> observer, IDisposable cancel)
                     : base(observer, cancel)
@@ -51,7 +48,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Predicate : Producer<bool>
+        internal sealed class Predicate : Producer<bool, Predicate._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, bool> _predicate;
@@ -62,14 +59,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _predicate = predicate;
             }
 
-            protected override IDisposable Run(IObserver<bool> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_predicate, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<bool> observer, IDisposable cancel) => new _(_predicate, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<bool>, IObserver<TSource>
+            internal sealed class _ : Sink<bool>, IObserver<TSource>
             {
                 private readonly Func<TSource, bool> _predicate;
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/AsObservable.cs

@@ -4,7 +4,7 @@
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class AsObservable<TSource> : Producer<TSource>, IEvaluatableObservable<TSource>
+    internal sealed class AsObservable<TSource> : Producer<TSource, AsObservable<TSource>._>, IEvaluatableObservable<TSource>
     {
         private readonly IObservable<TSource> _source;
 
@@ -15,14 +15,11 @@ namespace System.Reactive.Linq.ObservableImpl
 
         public IObservable<TSource> Eval() => _source;
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 50 - 80
Rx.NET/Source/src/System.Reactive/Linq/Observable/Average.cs

@@ -4,7 +4,7 @@
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class AverageDouble : Producer<double>
+    internal sealed class AverageDouble : Producer<double, AverageDouble._>
     {
         private readonly IObservable<double> _source;
 
@@ -13,14 +13,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<double> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<double> observer, IDisposable cancel) => new _(observer, cancel);
 
-        private sealed class _ : Sink<double>, IObserver<double>
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
+
+        internal sealed class _ : Sink<double>, IObserver<double>
         {
             private double _sum;
             private long _count;
@@ -72,7 +69,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class AverageSingle : Producer<float>
+    internal sealed class AverageSingle : Producer<float, AverageSingle._>
     {
         private readonly IObservable<float> _source;
 
@@ -81,14 +78,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<float> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<float> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<float>, IObserver<float>
+        internal sealed class _ : Sink<float>, IObserver<float>
         {
             private double _sum; // NOTE: Uses a different accumulator type (double), conform LINQ to Objects.
             private long _count;
@@ -140,7 +134,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class AverageDecimal : Producer<decimal>
+    internal sealed class AverageDecimal : Producer<decimal, AverageDecimal._>
     {
         private readonly IObservable<decimal> _source;
 
@@ -149,14 +143,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<decimal> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<decimal> observer, IDisposable cancel) => new _(observer, cancel);
 
-        private sealed class _ : Sink<decimal>, IObserver<decimal>
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
+
+        internal sealed class _ : Sink<decimal>, IObserver<decimal>
         {
             private decimal _sum;
             private long _count;
@@ -208,7 +199,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class AverageInt32 : Producer<double>
+    internal sealed class AverageInt32 : Producer<double, AverageInt32._>
     {
         private readonly IObservable<int> _source;
 
@@ -217,14 +208,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<double> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<double> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<double>, IObserver<int>
+        internal sealed class _ : Sink<double>, IObserver<int>
         {
             private long _sum;
             private long _count;
@@ -276,7 +264,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class AverageInt64 : Producer<double>
+    internal sealed class AverageInt64 : Producer<double, AverageInt64._>
     {
         private readonly IObservable<long> _source;
 
@@ -285,14 +273,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<double> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<double> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<double>, IObserver<long>
+        internal sealed class _ : Sink<double>, IObserver<long>
         {
             private long _sum;
             private long _count;
@@ -344,7 +329,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class AverageDoubleNullable : Producer<double?>
+    internal sealed class AverageDoubleNullable : Producer<double?, AverageDoubleNullable._>
     {
         private readonly IObservable<double?> _source;
 
@@ -353,14 +338,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<double?> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<double?> observer, IDisposable cancel) => new _(observer, cancel);
 
-        private sealed class _ : Sink<double?>, IObserver<double?>
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
+
+        internal sealed class _ : Sink<double?>, IObserver<double?>
         {
             private double _sum;
             private long _count;
@@ -415,7 +397,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class AverageSingleNullable : Producer<float?>
+    internal sealed class AverageSingleNullable : Producer<float?, AverageSingleNullable._>
     {
         private readonly IObservable<float?> _source;
 
@@ -424,14 +406,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<float?> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<float?> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<float?>, IObserver<float?>
+        internal sealed class _ : Sink<float?>, IObserver<float?>
         {
             private double _sum; // NOTE: Uses a different accumulator type (double), conform LINQ to Objects.
             private long _count;
@@ -486,7 +465,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class AverageDecimalNullable : Producer<decimal?>
+    internal sealed class AverageDecimalNullable : Producer<decimal?, AverageDecimalNullable._>
     {
         private readonly IObservable<decimal?> _source;
 
@@ -495,14 +474,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<decimal?> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<decimal?> observer, IDisposable cancel) => new _(observer, cancel);
 
-        private sealed class _ : Sink<decimal?>, IObserver<decimal?>
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
+
+        internal sealed class _ : Sink<decimal?>, IObserver<decimal?>
         {
             private decimal _sum;
             private long _count;
@@ -557,7 +533,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class AverageInt32Nullable : Producer<double?>
+    internal sealed class AverageInt32Nullable : Producer<double?, AverageInt32Nullable._>
     {
         private readonly IObservable<int?> _source;
 
@@ -566,14 +542,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<double?> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<double?> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<double?>, IObserver<int?>
+        internal sealed class _ : Sink<double?>, IObserver<int?>
         {
             private long _sum;
             private long _count;
@@ -628,7 +601,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class AverageInt64Nullable : Producer<double?>
+    internal sealed class AverageInt64Nullable : Producer<double?, AverageInt64Nullable._>
     {
         private readonly IObservable<long?> _source;
 
@@ -637,14 +610,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<double?> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<double?> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<double?>, IObserver<long?>
+        internal sealed class _ : Sink<double?>, IObserver<long?>
         {
             private long _sum;
             private long _count;

+ 30 - 48
Rx.NET/Source/src/System.Reactive/Linq/Observable/Buffer.cs

@@ -10,7 +10,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class Buffer<TSource>
     {
-        internal sealed class Count : Producer<IList<TSource>>
+        internal sealed class Count : Producer<IList<TSource>, Count._>
         {
             private readonly IObservable<TSource> _source;
             private readonly int _count;
@@ -23,14 +23,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _skip = skip;
             }
 
-            protected override IDisposable Run(IObserver<IList<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run(_source);
-            }
+            protected override _ CreateSink(IObserver<IList<TSource>> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-            private sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
             {
                 private readonly Queue<IList<TSource>> _queue = new Queue<IList<TSource>>();
 
@@ -102,7 +99,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class TimeSliding : Producer<IList<TSource>>
+        internal sealed class TimeSliding : Producer<IList<TSource>, TimeSliding._>
         {
             private readonly IObservable<TSource> _source;
 
@@ -118,14 +115,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _scheduler = scheduler;
             }
 
-            protected override IDisposable Run(IObserver<IList<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run(this);
-            }
+            protected override _ CreateSink(IObserver<IList<TSource>> observer, IDisposable cancel) => new _(this, observer, cancel);
 
-            private sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+            protected override IDisposable Run(_ sink) => sink.Run(this);
+
+            internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
             {
                 private readonly TimeSpan _timeShift;
                 private readonly IScheduler _scheduler;
@@ -262,7 +256,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class TimeHopping : Producer<IList<TSource>>
+        internal sealed class TimeHopping : Producer<IList<TSource>, TimeHopping._>
         {
             private readonly IObservable<TSource> _source;
 
@@ -276,14 +270,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _scheduler = scheduler;
             }
 
-            protected override IDisposable Run(IObserver<IList<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _( observer, cancel);
-                setSink(sink);
-                return sink.Run(this);
-            }
+            protected override _ CreateSink(IObserver<IList<TSource>> observer, IDisposable cancel) => new _(observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            private sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
             {
                 private readonly object _gate = new object();
 
@@ -344,7 +335,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Ferry : Producer<IList<TSource>>
+        internal sealed class Ferry : Producer<IList<TSource>, Ferry._>
         {
             private readonly IObservable<TSource> _source;
             private readonly int _count;
@@ -359,14 +350,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _scheduler = scheduler;
             }
 
-            protected override IDisposable Run(IObserver<IList<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run();
-            }
+            protected override _ CreateSink(IObserver<IList<TSource>> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run();
 
-            private sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
             {
                 private readonly Ferry _parent;
 
@@ -478,7 +466,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
     internal static class Buffer<TSource, TBufferClosing>
     {
-        internal sealed class Selector : Producer<IList<TSource>>
+        internal sealed class Selector : Producer<IList<TSource>, Selector._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<IObservable<TBufferClosing>> _bufferClosingSelector;
@@ -489,14 +477,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _bufferClosingSelector = bufferClosingSelector;
             }
 
-            protected override IDisposable Run(IObserver<IList<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run(_source);
-            }
+            protected override _ CreateSink(IObserver<IList<TSource>> observer, IDisposable cancel) => new _(this, observer, cancel);
 
-            private sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+            protected override IDisposable Run(_ sink) => sink.Run(_source);
+
+            internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
             {
                 private readonly object _gate = new object();
                 private readonly AsyncLock _bufferGate = new AsyncLock();
@@ -616,7 +601,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Boundaries : Producer<IList<TSource>>
+        internal sealed class Boundaries : Producer<IList<TSource>, Boundaries._>
         {
             private readonly IObservable<TSource> _source;
             private readonly IObservable<TBufferClosing> _bufferBoundaries;
@@ -627,14 +612,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _bufferBoundaries = bufferBoundaries;
             }
 
-            protected override IDisposable Run(IObserver<IList<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(observer, cancel);
-                setSink(sink);
-                return sink.Run(this);
-            }
+            protected override _ CreateSink(IObserver<IList<TSource>> observer, IDisposable cancel) => new _(observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            private sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
             {
                 private readonly object _gate = new object();
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Case.cs

@@ -7,7 +7,7 @@ using System.Reactive.Disposables;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Case<TValue, TResult> : Producer<TResult>, IEvaluatableObservable<TResult>
+    internal sealed class Case<TValue, TResult> : Producer<TResult, Case<TValue, TResult>._>, IEvaluatableObservable<TResult>
     {
         private readonly Func<TValue> _selector;
         private readonly IDictionary<TValue, IObservable<TResult>> _sources;
@@ -28,14 +28,11 @@ namespace System.Reactive.Linq.ObservableImpl
             return _defaultSource;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return sink.Run(this);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        private sealed class _ : Sink<TResult>, IObserver<TResult>
+        internal sealed class _ : Sink<TResult>, IObserver<TResult>
         {
             public _(IObserver<TResult> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Cast.cs

@@ -4,7 +4,7 @@
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Cast<TSource, TResult> : Producer<TResult> /* Could optimize further by deriving from Select<TResult> and providing Combine<TResult2>. We're not doing this (yet) for debuggability. */
+    internal sealed class Cast<TSource, TResult> : Producer<TResult, Cast<TSource, TResult>._> /* Could optimize further by deriving from Select<TResult> and providing Combine<TResult2>. We're not doing this (yet) for debuggability. */
     {
         private readonly IObservable<TSource> _source;
 
@@ -13,14 +13,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<TResult>, IObserver<TSource>
+        internal sealed class _ : Sink<TResult>, IObserver<TSource>
         {
             public _(IObserver<TResult> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/Catch.cs

@@ -7,7 +7,7 @@ using System.Reactive.Disposables;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Catch<TSource> : Producer<TSource>
+    internal sealed class Catch<TSource> : Producer<TSource, Catch<TSource>._>
     {
         private readonly IEnumerable<IObservable<TSource>> _sources;
 
@@ -16,14 +16,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _sources = sources;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return sink.Run(_sources);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_sources);
 
-        private sealed class _ : TailRecursiveSink<TSource>
+        internal sealed class _ : TailRecursiveSink<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)
@@ -80,7 +77,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class Catch<TSource, TException> : Producer<TSource> where TException : Exception
+    internal sealed class Catch<TSource, TException> : Producer<TSource, Catch<TSource, TException>._> where TException : Exception
     {
         private readonly IObservable<TSource> _source;
         private readonly Func<TException, IObservable<TSource>> _handler;
@@ -91,14 +88,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _handler = handler;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_handler, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_handler, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             private readonly Func<TException, IObservable<TSource>> _handler;
 

+ 71 - 113
Rx.NET/Source/src/System.Reactive/Linq/Observable/CombineLatest.Generated.cs

@@ -10,9 +10,9 @@ namespace System.Reactive.Linq.ObservableImpl
 
     /* The following code is generated by a T4 template. */
 
-    #region CombineLatest auto-generated code (4/17/2017 3:25:27 PM)
+    #region CombineLatest auto-generated code (4/20/2017 3:38:14 PM)
 
-    internal sealed class CombineLatest<T1, T2, T3, TResult> : Producer<TResult>
+    internal sealed class CombineLatest<T1, T2, T3, TResult> : Producer<TResult, CombineLatest<T1, T2, T3, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -27,14 +27,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3);
 
-        private sealed class _ : CombineLatestSink<TResult>
+        internal sealed class _ : CombineLatestSink<TResult>
         {
             private readonly Func<T1, T2, T3, TResult> _resultSelector;
 
@@ -69,7 +66,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class CombineLatest<T1, T2, T3, T4, TResult> : Producer<TResult>
+    internal sealed class CombineLatest<T1, T2, T3, T4, TResult> : Producer<TResult, CombineLatest<T1, T2, T3, T4, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -86,14 +83,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4);
 
-        private sealed class _ : CombineLatestSink<TResult>
+        internal sealed class _ : CombineLatestSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, TResult> _resultSelector;
 
@@ -131,7 +125,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class CombineLatest<T1, T2, T3, T4, T5, TResult> : Producer<TResult>
+    internal sealed class CombineLatest<T1, T2, T3, T4, T5, TResult> : Producer<TResult, CombineLatest<T1, T2, T3, T4, T5, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -150,14 +144,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5);
 
-        private sealed class _ : CombineLatestSink<TResult>
+        internal sealed class _ : CombineLatestSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, TResult> _resultSelector;
 
@@ -198,7 +189,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, TResult> : Producer<TResult>
+    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, TResult> : Producer<TResult, CombineLatest<T1, T2, T3, T4, T5, T6, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -219,14 +210,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
 
-        private sealed class _ : CombineLatestSink<TResult>
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6);
+
+        internal sealed class _ : CombineLatestSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, TResult> _resultSelector;
 
@@ -270,7 +258,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, T7, TResult> : Producer<TResult>
+    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, T7, TResult> : Producer<TResult, CombineLatest<T1, T2, T3, T4, T5, T6, T7, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -293,14 +281,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
 
-        private sealed class _ : CombineLatestSink<TResult>
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7);
+
+        internal sealed class _ : CombineLatestSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, T7, TResult> _resultSelector;
 
@@ -347,7 +332,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, TResult> : Producer<TResult>
+    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, TResult> : Producer<TResult, CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -372,14 +357,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8);
 
-        private sealed class _ : CombineLatestSink<TResult>
+        internal sealed class _ : CombineLatestSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult> _resultSelector;
 
@@ -429,7 +411,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> : Producer<TResult>
+    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> : Producer<TResult, CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -456,14 +438,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9);
 
-        private sealed class _ : CombineLatestSink<TResult>
+        internal sealed class _ : CombineLatestSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> _resultSelector;
 
@@ -516,7 +495,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> : Producer<TResult>
+    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> : Producer<TResult, CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -545,14 +524,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10);
 
-        private sealed class _ : CombineLatestSink<TResult>
+        internal sealed class _ : CombineLatestSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> _resultSelector;
 
@@ -608,7 +584,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> : Producer<TResult>
+    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> : Producer<TResult, CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -639,14 +615,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11);
 
-        private sealed class _ : CombineLatestSink<TResult>
+        internal sealed class _ : CombineLatestSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> _resultSelector;
 
@@ -705,7 +678,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> : Producer<TResult>
+    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> : Producer<TResult, CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -738,14 +711,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11, _source12);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11, _source12);
 
-        private sealed class _ : CombineLatestSink<TResult>
+        internal sealed class _ : CombineLatestSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> _resultSelector;
 
@@ -807,7 +777,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> : Producer<TResult>
+    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> : Producer<TResult, CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -842,14 +812,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11, _source12, _source13);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
 
-        private sealed class _ : CombineLatestSink<TResult>
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11, _source12, _source13);
+
+        internal sealed class _ : CombineLatestSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> _resultSelector;
 
@@ -914,7 +881,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> : Producer<TResult>
+    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> : Producer<TResult, CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -951,14 +918,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11, _source12, _source13, _source14);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
 
-        private sealed class _ : CombineLatestSink<TResult>
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11, _source12, _source13, _source14);
+
+        internal sealed class _ : CombineLatestSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> _resultSelector;
 
@@ -1026,7 +990,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> : Producer<TResult>
+    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> : Producer<TResult, CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -1065,14 +1029,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11, _source12, _source13, _source14, _source15);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11, _source12, _source13, _source14, _source15);
 
-        private sealed class _ : CombineLatestSink<TResult>
+        internal sealed class _ : CombineLatestSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> _resultSelector;
 
@@ -1143,7 +1104,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> : Producer<TResult>
+    internal sealed class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> : Producer<TResult, CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -1184,14 +1145,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11, _source12, _source13, _source14, _source15, _source16);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11, _source12, _source13, _source14, _source15, _source16);
 
-        private sealed class _ : CombineLatestSink<TResult>
+        internal sealed class _ : CombineLatestSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> _resultSelector;
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/CombineLatest.Generated.tt

@@ -26,7 +26,7 @@ for (var i = 3; i <= 16; i++)
     var vs = string.Join(", ", Enumerable.Range(1, i).Select(j => "_observer" + j + ".Value"));
     var ss = string.Join(", ", Enumerable.Range(1, i).Select(j => "_source" + j));
 #>
-    internal sealed class CombineLatest<<#=ts#>, TResult> : Producer<TResult>
+    internal sealed class CombineLatest<<#=ts#>, TResult> : Producer<TResult, CombineLatest<<#=ts#>, TResult>._>
     {
 <#
 for (var j = 1; j <= i; j++)
@@ -51,14 +51,11 @@ for (var j = 1; j <= i; j++)
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(<#=ss#>);
-        }
+        protected override _ CreateSink2(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(<#=ss#>);
 
-        private sealed class _ : CombineLatestSink<TResult>
+        internal sealed class _ : CombineLatestSink<TResult>
         {
             private readonly Func<<#=ts#>, TResult> _resultSelector;
 

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/CombineLatest.cs

@@ -11,7 +11,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     #region Binary
 
-    internal sealed class CombineLatest<TFirst, TSecond, TResult> : Producer<TResult>
+    internal sealed class CombineLatest<TFirst, TSecond, TResult> : Producer<TResult, CombineLatest<TFirst, TSecond, TResult>._>
     {
         private readonly IObservable<TFirst> _first;
         private readonly IObservable<TSecond> _second;
@@ -24,14 +24,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_first, _second);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_first, _second);
 
-        private sealed class _ : Sink<TResult>
+        internal sealed class _ : Sink<TResult>
         {
             private readonly Func<TFirst, TSecond, TResult> _resultSelector;
 
@@ -392,7 +389,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
     #region N-ary
 
-    internal sealed class CombineLatest<TSource, TResult> : Producer<TResult>
+    internal sealed class CombineLatest<TSource, TResult> : Producer<TResult, CombineLatest<TSource, TResult>._>
     {
         private readonly IEnumerable<IObservable<TSource>> _sources;
         private readonly Func<IList<TSource>, TResult> _resultSelector;
@@ -403,14 +400,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_sources);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_sources);
 
-        private sealed class _ : Sink<TResult>
+        internal sealed class _ : Sink<TResult>
         {
             private readonly Func<IList<TSource>, TResult> _resultSelector;
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Concat.cs

@@ -6,7 +6,7 @@ using System.Collections.Generic;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Concat<TSource> : Producer<TSource>, IConcatenatable<TSource>
+    internal sealed class Concat<TSource> : Producer<TSource, Concat<TSource>._>, IConcatenatable<TSource>
     {
         private readonly IEnumerable<IObservable<TSource>> _sources;
 
@@ -15,16 +15,13 @@ namespace System.Reactive.Linq.ObservableImpl
             _sources = sources;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return sink.Run(_sources);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_sources);
 
         public IEnumerable<IObservable<TSource>> GetSources() => _sources;
 
-        private sealed class _ : ConcatSink<TSource>
+        internal sealed class _ : ConcatSink<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Contains.cs

@@ -6,7 +6,7 @@ using System.Collections.Generic;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Contains<TSource> : Producer<bool>
+    internal sealed class Contains<TSource> : Producer<bool, Contains<TSource>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly TSource _value;
@@ -19,14 +19,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _comparer = comparer;
         }
 
-        protected override IDisposable Run(IObserver<bool> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(this, observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<bool> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<bool>, IObserver<TSource>
+        internal sealed class _ : Sink<bool>, IObserver<TSource>
         {
             private readonly TSource _value;
             private readonly IEqualityComparer<TSource> _comparer;

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/Count.cs

@@ -6,7 +6,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class Count<TSource>
     {
-        internal sealed class All : Producer<int>
+        internal sealed class All : Producer<int, All._>
         {
             private readonly IObservable<TSource> _source;
 
@@ -15,14 +15,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _source = source;
             }
 
-            protected override IDisposable Run(IObserver<int> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<int> observer, IDisposable cancel) => new _(observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<int>, IObserver<TSource>
+            internal sealed class _ : Sink<int>, IObserver<TSource>
             {
                 private int _count;
 
@@ -63,7 +60,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Predicate : Producer<int>
+        internal sealed class Predicate : Producer<int, Predicate._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, bool> _predicate;
@@ -74,14 +71,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _predicate = predicate;
             }
 
-            protected override IDisposable Run(IObserver<int> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_predicate, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<int> observer, IDisposable cancel) => new _(_predicate, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<int>, IObserver<TSource>
+            internal sealed class _ : Sink<int>, IObserver<TSource>
             {
                 private readonly Func<TSource, bool> _predicate;
                 private int _count;

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/DefaultIfEmpty.cs

@@ -4,7 +4,7 @@
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class DefaultIfEmpty<TSource> : Producer<TSource>
+    internal sealed class DefaultIfEmpty<TSource> : Producer<TSource, DefaultIfEmpty<TSource>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly TSource _defaultValue;
@@ -15,14 +15,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _defaultValue = defaultValue;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_defaultValue, observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_defaultValue, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             private readonly TSource _defaultValue;
             private bool _found;

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Defer.cs

@@ -6,7 +6,7 @@ using System.Reactive.Disposables;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Defer<TValue> : Producer<TValue>, IEvaluatableObservable<TValue>
+    internal sealed class Defer<TValue> : Producer<TValue, Defer<TValue>._>, IEvaluatableObservable<TValue>
     {
         private readonly Func<IObservable<TValue>> _observableFactory;
 
@@ -15,16 +15,13 @@ namespace System.Reactive.Linq.ObservableImpl
             _observableFactory = observableFactory;
         }
 
-        protected override IDisposable Run(IObserver<TValue> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_observableFactory, observer, cancel);
-            setSink(sink);
-            return sink.Run();
-        }
+        protected override _ CreateSink(IObserver<TValue> observer, IDisposable cancel) => new _(_observableFactory, observer, cancel);
+
+        protected override IDisposable Run(_ sink) =>sink.Run();
 
         public IObservable<TValue> Eval() => _observableFactory();
 
-        private sealed class _ : Sink<TValue>, IObserver<TValue>
+        internal sealed class _ : Sink<TValue>, IObserver<TValue>
         {
             private readonly Func<IObservable<TValue>> _observableFactory;
 

+ 85 - 84
Rx.NET/Source/src/System.Reactive/Linq/Observable/Delay.cs

@@ -11,7 +11,8 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class Delay<TSource>
     {
-        internal abstract class Base : Producer<TSource>
+        internal abstract class Base<TParent> : Producer<TSource, Base<TParent>._>
+            where TParent : Base<TParent>
         {
             protected readonly IObservable<TSource> _source;
             protected readonly IScheduler _scheduler;
@@ -22,15 +23,28 @@ namespace System.Reactive.Linq.ObservableImpl
                 _scheduler = scheduler;
             }
 
-            protected abstract class _<TParent> : Sink<TSource>, IObserver<TSource>
-                where TParent : Base
+            internal abstract class _ : Sink<TSource>, IObserver<TSource>
+            {
+                public _(IObserver<TSource> observer, IDisposable cancel)
+                    : base(observer, cancel)
+                {
+                }
+
+                public abstract void OnCompleted();
+                public abstract void OnError(Exception error);
+                public abstract void OnNext(TSource value);
+
+                public abstract IDisposable Run(TParent parent);
+            }
+
+            internal abstract class S : _
             {
                 protected readonly object _gate = new object();
                 protected readonly SerialDisposable _cancelable = new SerialDisposable();
 
                 protected readonly IScheduler _scheduler;
 
-                public _(TParent parent, IObserver<TSource> observer, IDisposable cancel)
+                public S(TParent parent, IObserver<TSource> observer, IDisposable cancel)
                     : base(observer, cancel)
                 {
                     _scheduler = parent._scheduler;
@@ -50,7 +64,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 private bool _hasFailed;
                 private Exception _exception;
 
-                public IDisposable Run(TParent parent)
+                public override IDisposable Run(TParent parent)
                 {
                     _active = false;
                     _running = false;
@@ -73,7 +87,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
                 protected abstract void RunCore(TParent parent);
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     var next = _watch.Elapsed.Add(_delay);
                     var shouldRun = false;
@@ -92,7 +106,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     _sourceSubscription.Dispose();
 
@@ -115,7 +129,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     _sourceSubscription.Dispose();
 
@@ -246,8 +260,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            protected abstract class L<TParent> : Sink<TSource>, IObserver<TSource>
-                where TParent : Base
+            protected abstract class L : _
             {
                 protected readonly object _gate = new object();
                 protected readonly SerialDisposable _cancelable = new SerialDisposable();
@@ -273,7 +286,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 private bool _hasFailed;
                 private Exception _exception;
 
-                public IDisposable Run(TParent parent)
+                public override IDisposable Run(TParent parent)
                 {
                     _queue = new Queue<System.Reactive.TimeInterval<TSource>>();
                     _hasCompleted = false;
@@ -302,7 +315,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     _scheduler.AsLongRunning().ScheduleLongRunning(DrainQueue);
                 }
 
-                public void OnNext(TSource value)
+                public override void OnNext(TSource value)
                 {
                     var next = _watch.Elapsed.Add(_delay);
 
@@ -314,7 +327,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnError(Exception error)
+                public override void OnError(Exception error)
                 {
                     _sourceSubscription.Dispose();
 
@@ -329,7 +342,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     }
                 }
 
-                public void OnCompleted()
+                public override void OnCompleted()
                 {
                     _sourceSubscription.Dispose();
 
@@ -444,7 +457,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Absolute : Base
+        internal sealed class Absolute : Base<Absolute>
         {
             private readonly DateTimeOffset _dueTime;
 
@@ -454,25 +467,13 @@ namespace System.Reactive.Linq.ObservableImpl
                 _dueTime = dueTime;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                if (_scheduler.AsLongRunning() != null)
-                {
-                    var sink = new L(this, observer, cancel);
-                    setSink(sink);
-                    return sink.Run(this);
-                }
-                else
-                {
-                    var sink = new _(this, observer, cancel);
-                    setSink(sink);
-                    return sink.Run(this);
-                }
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => _scheduler.AsLongRunning() != null ? (Base<Absolute>._)new L(this, observer, cancel) : new S(this, observer, cancel);
 
-            private sealed class _ : _<Absolute>
+            protected override IDisposable Run(_ sink) => sink.Run(this);
+
+            new private sealed class S : Base<Absolute>.S
             {
-                public _(Absolute parent, IObserver<TSource> observer, IDisposable cancel)
+                public S(Absolute parent, IObserver<TSource> observer, IDisposable cancel)
                     : base(parent, observer, cancel)
                 {
                 }
@@ -520,7 +521,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            private sealed class L : L<Absolute>
+            new private sealed class L : Base<Absolute>.L
             {
                 public L(Absolute parent, IObserver<TSource> observer, IDisposable cancel)
                     : base(parent, observer, cancel)
@@ -553,7 +554,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Relative : Base
+        internal sealed class Relative : Base<Relative>
         {
             private readonly TimeSpan _dueTime;
 
@@ -563,25 +564,13 @@ namespace System.Reactive.Linq.ObservableImpl
                 _dueTime = dueTime;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                if (_scheduler.AsLongRunning() != null)
-                {
-                    var sink = new L(this, observer, cancel);
-                    setSink(sink);
-                    return sink.Run(this);
-                }
-                else
-                {
-                    var sink = new _(this, observer, cancel);
-                    setSink(sink);
-                    return sink.Run(this);
-                }
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => _scheduler.AsLongRunning() != null ? (Base<Relative>._)new L(this, observer, cancel) : new S(this, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            private sealed class _ : _<Relative>
+            new private sealed class S : Base<Relative>.S
             {
-                public _(Relative parent, IObserver<TSource> observer, IDisposable cancel)
+                public S(Relative parent, IObserver<TSource> observer, IDisposable cancel)
                     : base(parent, observer, cancel)
                 {
                 }
@@ -594,7 +583,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            private sealed class L : L<Relative>
+            new private sealed class L : Base<Relative>.L
             {
                 public L(Relative parent, IObserver<TSource> observer, IDisposable cancel)
                     : base(parent, observer, cancel)
@@ -612,36 +601,27 @@ namespace System.Reactive.Linq.ObservableImpl
 
     internal static class Delay<TSource, TDelay>
     {
-        internal class Selector : Producer<TSource>
+        internal abstract class Base<TParent> : Producer<TSource, Base<TParent>._>
+            where TParent : Base<TParent>
         {
             protected readonly IObservable<TSource> _source;
-            private readonly Func<TSource, IObservable<TDelay>> _delaySelector;
 
-            public Selector(IObservable<TSource> source, Func<TSource, IObservable<TDelay>> delaySelector)
+            public Base(IObservable<TSource> source)
             {
                 _source = source;
-                _delaySelector = delaySelector;
-            }
-
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _<Selector>(this, observer, cancel);
-                setSink(sink);
-                return sink.Run(this);
             }
 
-            protected class _<TParent> : Sink<TSource>, IObserver<TSource>
-                where TParent : Selector
+            internal abstract class _ : Sink<TSource>, IObserver<TSource>
             {
                 private readonly CompositeDisposable _delays = new CompositeDisposable();
                 private object _gate = new object();
 
                 private readonly Func<TSource, IObservable<TDelay>> _delaySelector;
 
-                public _(Selector parent, IObserver<TSource> observer, IDisposable cancel)
+                public _(Func<TSource, IObservable<TDelay>> delaySelector, IObserver<TSource> observer, IDisposable cancel)
                     : base(observer, cancel)
                 {
-                    _delaySelector = parent._delaySelector;
+                    _delaySelector = delaySelector;
                 }
 
                 private bool _atEnd;
@@ -656,10 +636,7 @@ namespace System.Reactive.Linq.ObservableImpl
                     return StableCompositeDisposable.Create(_subscription, _delays);
                 }
 
-                protected virtual IDisposable RunCore(TParent parent)
-                {
-                    return parent._source.SubscribeSafe(this);
-                }
+                protected abstract IDisposable RunCore(TParent parent);
 
                 public void OnNext(TSource value)
                 {
@@ -715,11 +692,11 @@ namespace System.Reactive.Linq.ObservableImpl
 
                 private sealed class DelayObserver : IObserver<TDelay>
                 {
-                    private readonly _<TParent> _parent;
+                    private readonly _ _parent;
                     private readonly TSource _value;
                     private readonly IDisposable _self;
 
-                    public DelayObserver(_<TParent> parent, TSource value, IDisposable self)
+                    public DelayObserver(_ parent, TSource value, IDisposable self)
                     {
                         _parent = parent;
                         _value = value;
@@ -760,27 +737,51 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class SelectorWithSubscriptionDelay : Selector
+        internal class Selector : Base<Selector>
+        {
+            private readonly Func<TSource, IObservable<TDelay>> _delaySelector;
+
+            public Selector(IObservable<TSource> source, Func<TSource, IObservable<TDelay>> delaySelector)
+                : base(source)
+            {
+                _delaySelector = delaySelector;
+            }
+
+            protected override Base<Selector>._ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_delaySelector, observer, cancel);
+
+            protected override IDisposable Run(Base<Selector>._ sink) => sink.Run(this);
+
+            new private sealed class _ : Base<Selector>._
+            {
+                public _(Func<TSource, IObservable<TDelay>> delaySelector, IObserver<TSource> observer, IDisposable cancel)
+                    : base(delaySelector, observer, cancel)
+                {
+                }
+
+                protected override IDisposable RunCore(Selector parent) => parent._source.SubscribeSafe(this);
+            }
+        }
+
+        internal sealed class SelectorWithSubscriptionDelay : Base<SelectorWithSubscriptionDelay>
         {
             private readonly IObservable<TDelay> _subscriptionDelay;
+            private readonly Func<TSource, IObservable<TDelay>> _delaySelector;
 
             public SelectorWithSubscriptionDelay(IObservable<TSource> source, IObservable<TDelay> subscriptionDelay, Func<TSource, IObservable<TDelay>> delaySelector)
-                : base(source, delaySelector)
+                : base(source)
             {
                 _subscriptionDelay = subscriptionDelay;
+                _delaySelector = delaySelector;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run(this);
-            }
+            protected override Base<SelectorWithSubscriptionDelay>._ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_delaySelector, observer, cancel);
+
+            protected override IDisposable Run(Base<SelectorWithSubscriptionDelay>._ sink) => sink.Run(this);
 
-            private sealed class _ : _<SelectorWithSubscriptionDelay>
+            new private sealed class _ : Base<SelectorWithSubscriptionDelay>._
             {
-                public _(SelectorWithSubscriptionDelay parent, IObserver<TSource> observer, IDisposable cancel)
-                    : base(parent, observer, cancel)
+                public _(Func<TSource, IObservable<TDelay>> delaySelector, IObserver<TSource> observer, IDisposable cancel)
+                    : base(delaySelector, observer, cancel)
                 {
                 }
 

+ 8 - 14
Rx.NET/Source/src/System.Reactive/Linq/Observable/DelaySubscription.cs

@@ -6,7 +6,7 @@ using System.Reactive.Concurrency;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal abstract class DelaySubscription<TSource> : Producer<TSource>
+    internal abstract class DelaySubscription<TSource> : Producer<TSource, DelaySubscription<TSource>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly IScheduler _scheduler;
@@ -27,12 +27,9 @@ namespace System.Reactive.Linq.ObservableImpl
                 _dueTime = dueTime;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(observer, cancel);
-                setSink(sink);
-                return _scheduler.Schedule(sink, _dueTime, Subscribe);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _scheduler.Schedule(sink, _dueTime, Subscribe);
         }
 
         internal sealed class Absolute : DelaySubscription<TSource>
@@ -45,12 +42,9 @@ namespace System.Reactive.Linq.ObservableImpl
                 _dueTime = dueTime;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(observer, cancel);
-                setSink(sink);
-                return _scheduler.Schedule(sink, _dueTime, Subscribe);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _scheduler.Schedule(sink, _dueTime, Subscribe);
         }
 
         private IDisposable Subscribe(IScheduler _, _ sink)
@@ -58,7 +52,7 @@ namespace System.Reactive.Linq.ObservableImpl
             return _source.SubscribeSafe(sink);
         }
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Dematerialize.cs

@@ -4,7 +4,7 @@
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Dematerialize<TSource> : Producer<TSource>
+    internal sealed class Dematerialize<TSource> : Producer<TSource, Dematerialize<TSource>._>
     {
         private readonly IObservable<Notification<TSource>> _source;
 
@@ -13,14 +13,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<TSource>, IObserver<Notification<TSource>>
+        internal sealed class _ : Sink<TSource>, IObserver<Notification<TSource>>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Distinct.cs

@@ -6,7 +6,7 @@ using System.Collections.Generic;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Distinct<TSource, TKey> : Producer<TSource>
+    internal sealed class Distinct<TSource, TKey> : Producer<TSource, Distinct<TSource, TKey>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly Func<TSource, TKey> _keySelector;
@@ -19,14 +19,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _comparer = comparer;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(this, observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             private readonly Func<TSource, TKey> _keySelector;
             private HashSet<TKey> _hashSet;

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/DistinctUntilChanged.cs

@@ -6,7 +6,7 @@ using System.Collections.Generic;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class DistinctUntilChanged<TSource, TKey> : Producer<TSource>
+    internal sealed class DistinctUntilChanged<TSource, TKey> : Producer<TSource, DistinctUntilChanged<TSource, TKey>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly Func<TSource, TKey> _keySelector;
@@ -19,14 +19,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _comparer = comparer;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(this, observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             private readonly Func<TSource, TKey> _keySelector;
             private readonly IEqualityComparer<TKey> _comparer;

+ 15 - 24
Rx.NET/Source/src/System.Reactive/Linq/Observable/Do.cs

@@ -6,7 +6,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class Do<TSource>
     {
-        internal sealed class OnNext : Producer<TSource>
+        internal sealed class OnNext : Producer<TSource, OnNext._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Action<TSource> _onNext;
@@ -17,14 +17,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _onNext = onNext;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_onNext, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_onNext, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private readonly Action<TSource> _onNext;
 
@@ -64,7 +61,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Observer : Producer<TSource>
+        internal sealed class Observer : Producer<TSource, Observer._>
         {
             private readonly IObservable<TSource> _source;
             private readonly IObserver<TSource> _observer;
@@ -75,14 +72,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _observer = observer;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_observer, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_observer, observer, cancel);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
+
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private readonly IObserver<TSource> _doObserver;
 
@@ -144,7 +138,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Actions : Producer<TSource>
+        internal sealed class Actions : Producer<TSource, Actions._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Action<TSource> _onNext;
@@ -159,14 +153,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _onCompleted = onCompleted;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 // CONSIDER: This sink has a parent reference that can be considered for removal.
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/DoWhile.cs

@@ -6,7 +6,7 @@ using System.Collections.Generic;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class DoWhile<TSource> : Producer<TSource>, IConcatenatable<TSource>
+    internal sealed class DoWhile<TSource> : Producer<TSource, DoWhile<TSource>._>, IConcatenatable<TSource>
     {
         private readonly IObservable<TSource> _source;
         private readonly Func<bool> _condition;
@@ -17,12 +17,9 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return sink.Run(GetSources());
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(GetSources());
 
         public IEnumerable<IObservable<TSource>> GetSources()
         {
@@ -31,7 +28,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 yield return _source;
         }
 
-        private sealed class _ : ConcatSink<TSource>
+        internal sealed class _ : ConcatSink<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/ElementAt.cs

@@ -4,7 +4,7 @@
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class ElementAt<TSource> : Producer<TSource>
+    internal sealed class ElementAt<TSource> : Producer<TSource, ElementAt<TSource>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly int _index;
@@ -15,14 +15,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _index = index;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_index, observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_index, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             private int _i;
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/ElementAtOrDefault.cs

@@ -4,7 +4,7 @@
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class ElementAtOrDefault<TSource> : Producer<TSource>
+    internal sealed class ElementAtOrDefault<TSource> : Producer<TSource, ElementAtOrDefault<TSource>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly int _index;
@@ -15,14 +15,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _index = index;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_index, observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_index, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             private int _i;
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Empty.cs

@@ -6,7 +6,7 @@ using System.Reactive.Concurrency;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Empty<TResult> : Producer<TResult>
+    internal sealed class Empty<TResult> : Producer<TResult, Empty<TResult>._>
     {
         private readonly IScheduler _scheduler;
 
@@ -15,14 +15,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _scheduler = scheduler;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return sink.Run(_scheduler);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_scheduler);
 
-        private sealed class _ : Sink<TResult>
+        internal sealed class _ : Sink<TResult>
         {
             public _(IObserver<TResult> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Finally.cs

@@ -6,7 +6,7 @@ using System.Reactive.Disposables;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Finally<TSource> : Producer<TSource>
+    internal sealed class Finally<TSource> : Producer<TSource, Finally<TSource>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly Action _finallyAction;
@@ -17,14 +17,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _finallyAction = finallyAction;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_finallyAction, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_finallyAction, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             private readonly Action _finallyAction;
 

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/FirstAsync.cs

@@ -6,7 +6,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class FirstAsync<TSource>
     {
-        internal sealed class Sequence : Producer<TSource>
+        internal sealed class Sequence : Producer<TSource, Sequence._>
         {
             private readonly IObservable<TSource> _source;
 
@@ -15,14 +15,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _source = source;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 public _(IObserver<TSource> observer, IDisposable cancel)
                     : base(observer, cancel)
@@ -50,7 +47,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Predicate : Producer<TSource>
+        internal sealed class Predicate : Producer<TSource, Predicate._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, bool> _predicate;
@@ -61,14 +58,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _predicate = predicate;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_predicate, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_predicate, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private readonly Func<TSource, bool> _predicate;
 

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/FirstOrDefaultAsync.cs

@@ -6,7 +6,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class FirstOrDefaultAsync<TSource>
     {
-        internal sealed class Sequence : Producer<TSource>
+        internal sealed class Sequence : Producer<TSource, Sequence._>
         {
             private readonly IObservable<TSource> _source;
 
@@ -15,14 +15,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _source = source;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 public _(IObserver<TSource> observer, IDisposable cancel)
                     : base(observer, cancel)
@@ -51,7 +48,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Predicate : Producer<TSource>
+        internal sealed class Predicate : Producer<TSource, Predicate._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, bool> _predicate;
@@ -62,14 +59,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _predicate = predicate;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_predicate, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_predicate, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private readonly Func<TSource, bool> _predicate;
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/For.cs

@@ -6,7 +6,7 @@ using System.Collections.Generic;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class For<TSource, TResult> : Producer<TResult>, IConcatenatable<TResult>
+    internal sealed class For<TSource, TResult> : Producer<TResult, For<TSource, TResult>._>, IConcatenatable<TResult>
     {
         private readonly IEnumerable<TSource> _source;
         private readonly Func<TSource, IObservable<TResult>> _resultSelector;
@@ -17,12 +17,9 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return sink.Run(GetSources());
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(GetSources());
 
         public IEnumerable<IObservable<TResult>> GetSources()
         {
@@ -30,7 +27,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 yield return _resultSelector(item);
         }
 
-        private sealed class _ : ConcatSink<TResult>
+        internal sealed class _ : ConcatSink<TResult>
         {
             public _(IObserver<TResult> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 2 - 2
Rx.NET/Source/src/System.Reactive/Linq/Observable/FromEvent.cs

@@ -190,7 +190,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal abstract class EventProducer<TDelegate, TArgs> : Producer<TArgs>
+    internal abstract class EventProducer<TDelegate, TArgs> : BasicProducer<TArgs>
     {
         private readonly IScheduler _scheduler;
         private readonly object _gate;
@@ -206,7 +206,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
         private Session _session;
 
-        protected override IDisposable Run(IObserver<TArgs> observer, IDisposable cancel, Action<IDisposable> setSink)
+        protected override IDisposable Run(IObserver<TArgs> observer)
         {
             var connection = default(IDisposable);
 

+ 15 - 24
Rx.NET/Source/src/System.Reactive/Linq/Observable/Generate.cs

@@ -9,7 +9,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class Generate<TState, TResult>
     {
-        internal sealed class NoTime : Producer<TResult>
+        internal sealed class NoTime : Producer<TResult, NoTime._>
         {
             private readonly TState _initialState;
             private readonly Func<TState, bool> _condition;
@@ -26,14 +26,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _scheduler = scheduler;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run();
-            }
+            protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run();
 
-            private sealed class _ : Sink<TResult>
+            internal sealed class _ : Sink<TResult>
             {
                 // CONSIDER: This sink has a parent reference that can be considered for removal.
 
@@ -156,7 +153,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Absolute : Producer<TResult>
+        internal sealed class Absolute : Producer<TResult, Absolute._>
         {
             private readonly TState _initialState;
             private readonly Func<TState, bool> _condition;
@@ -175,14 +172,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _scheduler = scheduler;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run();
-            }
+            protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(this, observer, cancel);
 
-            private sealed class _ : Sink<TResult>
+            protected override IDisposable Run(_ sink) => sink.Run();
+
+            internal sealed class _ : Sink<TResult>
             {
                 // CONSIDER: This sink has a parent reference that can be considered for removal.
 
@@ -254,7 +248,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Relative : Producer<TResult>
+        internal sealed class Relative : Producer<TResult, Relative._>
         {
             private readonly TState _initialState;
             private readonly Func<TState, bool> _condition;
@@ -273,14 +267,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _scheduler = scheduler;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run();
-            }
+            protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run();
 
-            private sealed class _ : Sink<TResult>
+            internal sealed class _ : Sink<TResult>
             {
                 // CONSIDER: This sink has a parent reference that can be considered for removal.
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/GroupBy.cs

@@ -8,7 +8,7 @@ using System.Reactive.Subjects;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class GroupBy<TSource, TKey, TElement> : Producer<IGroupedObservable<TKey, TElement>>
+    internal sealed class GroupBy<TSource, TKey, TElement> : Producer<IGroupedObservable<TKey, TElement>, GroupBy<TSource, TKey, TElement>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly Func<TSource, TKey> _keySelector;
@@ -25,14 +25,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _comparer = comparer;
         }
 
-        protected override IDisposable Run(IObserver<IGroupedObservable<TKey, TElement>> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(this, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source);
-        }
+        protected override _ CreateSink(IObserver<IGroupedObservable<TKey, TElement>> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-        private sealed class _ : Sink<IGroupedObservable<TKey, TElement>>, IObserver<TSource>
+        internal sealed class _ : Sink<IGroupedObservable<TKey, TElement>>, IObserver<TSource>
         {
             private readonly Func<TSource, TKey> _keySelector;
             private readonly Func<TSource, TElement> _elementSelector;

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/GroupByUntil.cs

@@ -10,7 +10,7 @@ using System.Reactive.Subjects;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class GroupByUntil<TSource, TKey, TElement, TDuration> : Producer<IGroupedObservable<TKey, TElement>>
+    internal sealed class GroupByUntil<TSource, TKey, TElement, TDuration> : Producer<IGroupedObservable<TKey, TElement>, GroupByUntil<TSource, TKey, TElement, TDuration>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly Func<TSource, TKey> _keySelector;
@@ -29,14 +29,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _comparer = comparer;
         }
 
-        protected override IDisposable Run(IObserver<IGroupedObservable<TKey, TElement>> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(this, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source);
-        }
+        protected override _ CreateSink(IObserver<IGroupedObservable<TKey, TElement>> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-        private sealed class _ : Sink<IGroupedObservable<TKey, TElement>>, IObserver<TSource>
+        internal sealed class _ : Sink<IGroupedObservable<TKey, TElement>>, IObserver<TSource>
         {
             private readonly object _nullGate = new object();
             private readonly CompositeDisposable _groupDisposable = new CompositeDisposable();

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/GroupJoin.cs

@@ -8,7 +8,7 @@ using System.Reactive.Subjects;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class GroupJoin<TLeft, TRight, TLeftDuration, TRightDuration, TResult> : Producer<TResult>
+    internal sealed class GroupJoin<TLeft, TRight, TLeftDuration, TRightDuration, TResult> : Producer<TResult, GroupJoin<TLeft, TRight, TLeftDuration, TRightDuration, TResult>._>
     {
         private readonly IObservable<TLeft> _left;
         private readonly IObservable<TRight> _right;
@@ -25,14 +25,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(this, observer, cancel);
-            setSink(sink);
-            return sink.Run(this);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        private sealed class _ : Sink<TResult>
+        internal sealed class _ : Sink<TResult>
         {
             private readonly object _gate = new object();
             private readonly CompositeDisposable _group = new CompositeDisposable();

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/If.cs

@@ -6,7 +6,7 @@ using System.Reactive.Disposables;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class If<TResult> : Producer<TResult>, IEvaluatableObservable<TResult>
+    internal sealed class If<TResult> : Producer<TResult, If<TResult>._>, IEvaluatableObservable<TResult>
     {
         private readonly Func<bool> _condition;
         private readonly IObservable<TResult> _thenSource;
@@ -21,14 +21,11 @@ namespace System.Reactive.Linq.ObservableImpl
 
         public IObservable<TResult> Eval() => _condition() ? _thenSource : _elseSource;
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(this, observer, cancel);
-            setSink(sink);
-            return sink.Run();
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run();
 
-        private sealed class _ : Sink<TResult>, IObserver<TResult>
+        internal sealed class _ : Sink<TResult>, IObserver<TResult>
         {
             private readonly If<TResult> _parent;
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/IgnoreElements.cs

@@ -4,7 +4,7 @@
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class IgnoreElements<TSource> : Producer<TSource>
+    internal sealed class IgnoreElements<TSource> : Producer<TSource, IgnoreElements<TSource>._>
     {
         private readonly IObservable<TSource> _source;
 
@@ -13,14 +13,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/IsEmpty.cs

@@ -4,7 +4,7 @@
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class IsEmpty<TSource> : Producer<bool>
+    internal sealed class IsEmpty<TSource> : Producer<bool, IsEmpty<TSource>._>
     {
         private readonly IObservable<TSource> _source;
 
@@ -13,14 +13,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<bool> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<bool> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<bool>, IObserver<TSource>
+        internal sealed class _ : Sink<bool>, IObserver<TSource>
         {
             public _(IObserver<bool> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Join.cs

@@ -7,7 +7,7 @@ using System.Reactive.Disposables;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Join<TLeft, TRight, TLeftDuration, TRightDuration, TResult> : Producer<TResult>
+    internal sealed class Join<TLeft, TRight, TLeftDuration, TRightDuration, TResult> : Producer<TResult, Join<TLeft, TRight, TLeftDuration, TRightDuration, TResult>._>
     {
         private readonly IObservable<TLeft> _left;
         private readonly IObservable<TRight> _right;
@@ -24,14 +24,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(this, observer, cancel);
-            setSink(sink);
-            return sink.Run(this);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        private sealed class _ : Sink<TResult>
+        internal sealed class _ : Sink<TResult>
         {
             private readonly object _gate = new object();
             private readonly CompositeDisposable _group = new CompositeDisposable();

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/LastAsync.cs

@@ -6,7 +6,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class LastAsync<TSource>
     {
-        internal sealed class Sequence : Producer<TSource>
+        internal sealed class Sequence : Producer<TSource, Sequence._>
         {
             private readonly IObservable<TSource> _source;
 
@@ -15,14 +15,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _source = source;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private TSource _value;
                 private bool _seenValue;
@@ -63,7 +60,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Predicate : Producer<TSource>
+        internal sealed class Predicate : Producer<TSource, Predicate._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, bool> _predicate;
@@ -74,14 +71,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _predicate = predicate;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_predicate, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_predicate, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private readonly Func<TSource, bool> _predicate;
                 private TSource _value;

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/LastOrDefaultAsync.cs

@@ -6,7 +6,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class LastOrDefaultAsync<TSource>
     {
-        internal sealed class Sequence : Producer<TSource>
+        internal sealed class Sequence : Producer<TSource, Sequence._>
         {
             private readonly IObservable<TSource> _source;
 
@@ -15,14 +15,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _source = source;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private TSource _value;
 
@@ -52,7 +49,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Predicate : Producer<TSource>
+        internal sealed class Predicate : Producer<TSource, Predicate._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, bool> _predicate;
@@ -63,14 +60,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _predicate = predicate;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_predicate, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_predicate, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private readonly Func<TSource, bool> _predicate;
                 private TSource _value;

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/LongCount.cs

@@ -6,7 +6,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class LongCount<TSource>
     {
-        internal sealed class All : Producer<long>
+        internal sealed class All : Producer<long, All._>
         {
             private readonly IObservable<TSource> _source;
 
@@ -15,14 +15,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _source = source;
             }
 
-            protected override IDisposable Run(IObserver<long> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<long> observer, IDisposable cancel) => new _(observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<long>, IObserver<TSource>
+            internal sealed class _ : Sink<long>, IObserver<TSource>
             {
                 private long _count;
 
@@ -63,7 +60,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Predicate : Producer<long>
+        internal sealed class Predicate : Producer<long, Predicate._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, bool> _predicate;
@@ -74,14 +71,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _predicate = predicate;
             }
 
-            protected override IDisposable Run(IObserver<long> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_predicate, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<long> observer, IDisposable cancel) => new _(_predicate, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<long>, IObserver<TSource>
+            internal sealed class _ : Sink<long>, IObserver<TSource>
             {
                 private readonly Func<TSource, bool> _predicate;
                 private long _count;

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Materialize.cs

@@ -4,7 +4,7 @@
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Materialize<TSource> : Producer<Notification<TSource>>
+    internal sealed class Materialize<TSource> : Producer<Notification<TSource>, Materialize<TSource>._>
     {
         private readonly IObservable<TSource> _source;
 
@@ -15,14 +15,11 @@ namespace System.Reactive.Linq.ObservableImpl
 
         public IObservable<TSource> Dematerialize() => _source.AsObservable();
 
-        protected override IDisposable Run(IObserver<Notification<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<Notification<TSource>> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<Notification<TSource>>, IObserver<TSource>
+        internal sealed class _ : Sink<Notification<TSource>>, IObserver<TSource>
         {
             public _(IObserver<Notification<TSource>> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 75 - 109
Rx.NET/Source/src/System.Reactive/Linq/Observable/Max.cs

@@ -6,7 +6,7 @@ using System.Collections.Generic;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Max<TSource> : Producer<TSource>
+    internal sealed class Max<TSource> : Producer<TSource, Max<TSource>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly IComparer<TSource> _comparer;
@@ -17,39 +17,38 @@ namespace System.Reactive.Linq.ObservableImpl
             _comparer = comparer;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => default(TSource) == null ? (_)new Null(_comparer, observer, cancel) : new NonNull(_comparer, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
+
+        internal abstract class _ : Sink<TSource>, IObserver<TSource>
         {
-            // LINQ to Objects makes this distinction in order to make [Max|Max] of an empty collection of reference type objects equal to null.
-            if (default(TSource) == null)
-            {
-                var sink = new Null(_comparer, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
-            else
+            protected readonly IComparer<TSource> _comparer;
+
+            public _(IComparer<TSource> comparer, IObserver<TSource> observer, IDisposable cancel)
+                : base(observer, cancel)
             {
-                var sink = new NonNull(_comparer, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
+                _comparer = comparer;
             }
+
+            public abstract void OnCompleted();
+            public abstract void OnError(Exception error);
+            public abstract void OnNext(TSource value);
         }
 
-        private sealed class NonNull : Sink<TSource>, IObserver<TSource>
+        private sealed class NonNull : _
         {
-            private readonly IComparer<TSource> _comparer;
             private bool _hasValue;
             private TSource _lastValue;
 
             public NonNull(IComparer<TSource> comparer, IObserver<TSource> observer, IDisposable cancel)
-                : base(observer, cancel)
+                : base(comparer, observer, cancel)
             {
-                _comparer = comparer;
-
                 _hasValue = false;
                 _lastValue = default(TSource);
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 if (_hasValue)
                 {
@@ -78,13 +77,13 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
+            public override void OnError(Exception error)
             {
                 base._observer.OnError(error);
                 base.Dispose();
             }
 
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (!_hasValue)
                 {
@@ -100,20 +99,17 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        private sealed class Null : Sink<TSource>, IObserver<TSource>
+        private sealed class Null : _
         {
-            private readonly IComparer<TSource> _comparer;
             private TSource _lastValue;
 
             public Null(IComparer<TSource> comparer, IObserver<TSource> observer, IDisposable cancel)
-                : base(observer, cancel)
+                : base(comparer, observer, cancel)
             {
-                _comparer = comparer;
-
                 _lastValue = default(TSource);
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 if (value != null)
                 {
@@ -144,13 +140,13 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
+            public override void OnError(Exception error)
             {
                 base._observer.OnError(error);
                 base.Dispose();
             }
 
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 base._observer.OnNext(_lastValue);
                 base._observer.OnCompleted();
@@ -159,7 +155,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class MaxDouble : Producer<double>
+    internal sealed class MaxDouble : Producer<double, MaxDouble._>
     {
         private readonly IObservable<double> _source;
 
@@ -168,14 +164,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<double> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<double> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<double>, IObserver<double>
+        internal sealed class _ : Sink<double>, IObserver<double>
         {
             private bool _hasValue;
             private double _lastValue;
@@ -226,7 +219,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class MaxSingle : Producer<float>
+    internal sealed class MaxSingle : Producer<float, MaxSingle._>
     {
         private readonly IObservable<float> _source;
 
@@ -235,14 +228,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<float> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<float> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<float>, IObserver<float>
+        internal sealed class _ : Sink<float>, IObserver<float>
         {
             private bool _hasValue;
             private float _lastValue;
@@ -293,7 +283,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class MaxDecimal : Producer<decimal>
+    internal sealed class MaxDecimal : Producer<decimal, MaxDecimal._>
     {
         private readonly IObservable<decimal> _source;
 
@@ -302,14 +292,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<decimal> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<decimal> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<decimal>, IObserver<decimal>
+        internal sealed class _ : Sink<decimal>, IObserver<decimal>
         {
             private bool _hasValue;
             private decimal _lastValue;
@@ -360,7 +347,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class MaxInt32 : Producer<int>
+    internal sealed class MaxInt32 : Producer<int, MaxInt32._>
     {
         private readonly IObservable<int> _source;
 
@@ -369,14 +356,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<int> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<int> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<int>, IObserver<int>
+        internal sealed class _ : Sink<int>, IObserver<int>
         {
             private bool _hasValue;
             private int _lastValue;
@@ -427,7 +411,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class MaxInt64 : Producer<long>
+    internal sealed class MaxInt64 : Producer<long, MaxInt64._>
     {
         private readonly IObservable<long> _source;
 
@@ -436,14 +420,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<long> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<long> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<long>, IObserver<long>
+        internal sealed class _ : Sink<long>, IObserver<long>
         {
             private bool _hasValue;
             private long _lastValue;
@@ -494,7 +475,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class MaxDoubleNullable : Producer<double?>
+    internal sealed class MaxDoubleNullable : Producer<double?, MaxDoubleNullable._>
     {
         private readonly IObservable<double?> _source;
 
@@ -503,14 +484,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<double?> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<double?> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<double?>, IObserver<double?>
+        internal sealed class _ : Sink<double?>, IObserver<double?>
         {
             private double? _lastValue;
 
@@ -553,7 +531,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class MaxSingleNullable : Producer<float?>
+    internal sealed class MaxSingleNullable : Producer<float?, MaxSingleNullable._>
     {
         private readonly IObservable<float?> _source;
 
@@ -562,14 +540,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<float?> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<float?> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<float?>, IObserver<float?>
+        internal sealed class _ : Sink<float?>, IObserver<float?>
         {
             private float? _lastValue;
 
@@ -612,7 +587,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class MaxDecimalNullable : Producer<decimal?>
+    internal sealed class MaxDecimalNullable : Producer<decimal?, MaxDecimalNullable._>
     {
         private readonly IObservable<decimal?> _source;
 
@@ -621,14 +596,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<decimal?> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<decimal?> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<decimal?>, IObserver<decimal?>
+        internal sealed class _ : Sink<decimal?>, IObserver<decimal?>
         {
             private decimal? _lastValue;
 
@@ -671,7 +643,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class MaxInt32Nullable : Producer<int?>
+    internal sealed class MaxInt32Nullable : Producer<int?, MaxInt32Nullable._>
     {
         private readonly IObservable<int?> _source;
 
@@ -680,14 +652,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<int?> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<int?> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<int?>, IObserver<int?>
+        internal sealed class _ : Sink<int?>, IObserver<int?>
         {
             private int? _lastValue;
 
@@ -730,7 +699,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class MaxInt64Nullable : Producer<long?>
+    internal sealed class MaxInt64Nullable : Producer<long?, MaxInt64Nullable._>
     {
         private readonly IObservable<long?> _source;
 
@@ -739,14 +708,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<long?> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<long?> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<long?>, IObserver<long?>
+        internal sealed class _ : Sink<long?>, IObserver<long?>
         {
             private long? _lastValue;
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/MaxBy.cs

@@ -6,7 +6,7 @@ using System.Collections.Generic;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class MaxBy<TSource, TKey> : Producer<IList<TSource>>
+    internal sealed class MaxBy<TSource, TKey> : Producer<IList<TSource>, MaxBy<TSource, TKey>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly Func<TSource, TKey> _keySelector;
@@ -19,14 +19,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _comparer = comparer;
         }
 
-        protected override IDisposable Run(IObserver<IList<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(this, observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<IList<TSource>> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+        internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
         {
             private readonly MaxBy<TSource, TKey> _parent;
             private bool _hasValue;

+ 15 - 24
Rx.NET/Source/src/System.Reactive/Linq/Observable/Merge.cs

@@ -11,7 +11,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class Merge<TSource>
     {
-        internal sealed class ObservablesMaxConcurrency : Producer<TSource>
+        internal sealed class ObservablesMaxConcurrency : Producer<TSource, ObservablesMaxConcurrency._>
         {
             private readonly IObservable<IObservable<TSource>> _sources;
             private readonly int _maxConcurrent;
@@ -22,14 +22,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _maxConcurrent = maxConcurrent;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_maxConcurrent, observer, cancel);
-                setSink(sink);
-                return sink.Run(this);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_maxConcurrent, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            private sealed class _ : Sink<TSource>, IObserver<IObservable<TSource>>
+            internal sealed class _ : Sink<TSource>, IObserver<IObservable<TSource>>
             {
                 private readonly int _maxConcurrent;
 
@@ -159,7 +156,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Observables : Producer<TSource>
+        internal sealed class Observables : Producer<TSource, Observables._>
         {
             private readonly IObservable<IObservable<TSource>> _sources;
 
@@ -168,14 +165,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _sources = sources;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(observer, cancel);
-                setSink(sink);
-                return sink.Run(this);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
 
-            private sealed class _ : Sink<TSource>, IObserver<IObservable<TSource>>
+            protected override IDisposable Run(_ sink) => sink.Run(this);
+
+            internal sealed class _ : Sink<TSource>, IObserver<IObservable<TSource>>
             {
                 public _(IObserver<TSource> observer, IDisposable cancel)
                     : base(observer, cancel)
@@ -289,7 +283,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Tasks : Producer<TSource>
+        internal sealed class Tasks : Producer<TSource, Tasks._>
         {
             private readonly IObservable<Task<TSource>> _sources;
 
@@ -298,14 +292,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _sources = sources;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(observer, cancel);
-                setSink(sink);
-                return sink.Run(this);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            private sealed class _ : Sink<TSource>, IObserver<Task<TSource>>
+            internal sealed class _ : Sink<TSource>, IObserver<Task<TSource>>
             {
                 public _(IObserver<TSource> observer, IDisposable cancel)
                     : base(observer, cancel)

+ 75 - 109
Rx.NET/Source/src/System.Reactive/Linq/Observable/Min.cs

@@ -6,7 +6,7 @@ using System.Collections.Generic;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Min<TSource> : Producer<TSource>
+    internal sealed class Min<TSource> : Producer<TSource, Min<TSource>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly IComparer<TSource> _comparer;
@@ -17,39 +17,38 @@ namespace System.Reactive.Linq.ObservableImpl
             _comparer = comparer;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => default(TSource) == null ? (_)new Null(_comparer, observer, cancel) : new NonNull(_comparer, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
+
+        internal abstract class _ : Sink<TSource>, IObserver<TSource>
         {
-            // LINQ to Objects makes this distinction in order to make [Min|Max] of an empty collection of reference type objects equal to null.
-            if (default(TSource) == null)
-            {
-                var sink = new Null(_comparer, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
-            else
+            protected readonly IComparer<TSource> _comparer;
+
+            public _(IComparer<TSource> comparer, IObserver<TSource> observer, IDisposable cancel)
+                : base(observer, cancel)
             {
-                var sink = new NonNull(_comparer, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
+                _comparer = comparer;
             }
+
+            public abstract void OnCompleted();
+            public abstract void OnError(Exception error);
+            public abstract void OnNext(TSource value);
         }
 
-        private sealed class NonNull : Sink<TSource>, IObserver<TSource>
+        private sealed class NonNull : _
         {
-            private readonly IComparer<TSource> _comparer;
             private bool _hasValue;
             private TSource _lastValue;
 
             public NonNull(IComparer<TSource> comparer, IObserver<TSource> observer, IDisposable cancel)
-                : base(observer, cancel)
+                : base(comparer, observer, cancel)
             {
-                _comparer = comparer;
-
                 _hasValue = false;
                 _lastValue = default(TSource);
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 if (_hasValue)
                 {
@@ -78,13 +77,13 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
+            public override void OnError(Exception error)
             {
                 base._observer.OnError(error);
                 base.Dispose();
             }
 
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 if (!_hasValue)
                 {
@@ -100,20 +99,17 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        private sealed class Null : Sink<TSource>, IObserver<TSource>
+        private sealed class Null : _
         {
-            private readonly IComparer<TSource> _comparer;
             private TSource _lastValue;
 
             public Null(IComparer<TSource> comparer, IObserver<TSource> observer, IDisposable cancel)
-                : base(observer, cancel)
+                : base(comparer, observer, cancel)
             {
-                _comparer = comparer;
-
                 _lastValue = default(TSource);
             }
 
-            public void OnNext(TSource value)
+            public override void OnNext(TSource value)
             {
                 if (value != null)
                 {
@@ -144,13 +140,13 @@ namespace System.Reactive.Linq.ObservableImpl
                 }
             }
 
-            public void OnError(Exception error)
+            public override void OnError(Exception error)
             {
                 base._observer.OnError(error);
                 base.Dispose();
             }
 
-            public void OnCompleted()
+            public override void OnCompleted()
             {
                 base._observer.OnNext(_lastValue);
                 base._observer.OnCompleted();
@@ -159,7 +155,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class MinDouble : Producer<double>
+    internal sealed class MinDouble : Producer<double, MinDouble._>
     {
         private readonly IObservable<double> _source;
 
@@ -168,14 +164,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<double> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<double> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<double>, IObserver<double>
+        internal sealed class _ : Sink<double>, IObserver<double>
         {
             private bool _hasValue;
             private double _lastValue;
@@ -226,7 +219,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class MinSingle : Producer<float>
+    internal sealed class MinSingle : Producer<float, MinSingle._>
     {
         private readonly IObservable<float> _source;
 
@@ -235,14 +228,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<float> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<float> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<float>, IObserver<float>
+        internal sealed class _ : Sink<float>, IObserver<float>
         {
             private bool _hasValue;
             private float _lastValue;
@@ -293,7 +283,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class MinDecimal : Producer<decimal>
+    internal sealed class MinDecimal : Producer<decimal, MinDecimal._>
     {
         private readonly IObservable<decimal> _source;
 
@@ -302,14 +292,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<decimal> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<decimal> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<decimal>, IObserver<decimal>
+        internal sealed class _ : Sink<decimal>, IObserver<decimal>
         {
             private bool _hasValue;
             private decimal _lastValue;
@@ -360,7 +347,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class MinInt32 : Producer<int>
+    internal sealed class MinInt32 : Producer<int, MinInt32._>
     {
         private readonly IObservable<int> _source;
 
@@ -369,14 +356,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<int> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<int> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<int>, IObserver<int>
+        internal sealed class _ : Sink<int>, IObserver<int>
         {
             private bool _hasValue;
             private int _lastValue;
@@ -427,7 +411,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class MinInt64 : Producer<long>
+    internal sealed class MinInt64 : Producer<long, MinInt64._>
     {
         private readonly IObservable<long> _source;
 
@@ -436,14 +420,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<long> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<long> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<long>, IObserver<long>
+        internal sealed class _ : Sink<long>, IObserver<long>
         {
             private bool _hasValue;
             private long _lastValue;
@@ -494,7 +475,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class MinDoubleNullable : Producer<double?>
+    internal sealed class MinDoubleNullable : Producer<double?, MinDoubleNullable._>
     {
         private readonly IObservable<double?> _source;
 
@@ -503,14 +484,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<double?> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<double?> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<double?>, IObserver<double?>
+        internal sealed class _ : Sink<double?>, IObserver<double?>
         {
             private double? _lastValue;
 
@@ -553,7 +531,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class MinSingleNullable : Producer<float?>
+    internal sealed class MinSingleNullable : Producer<float?, MinSingleNullable._>
     {
         private readonly IObservable<float?> _source;
 
@@ -562,14 +540,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<float?> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<float?> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<float?>, IObserver<float?>
+        internal sealed class _ : Sink<float?>, IObserver<float?>
         {
             private float? _lastValue;
 
@@ -612,7 +587,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class MinDecimalNullable : Producer<decimal?>
+    internal sealed class MinDecimalNullable : Producer<decimal?, MinDecimalNullable._>
     {
         private readonly IObservable<decimal?> _source;
 
@@ -621,14 +596,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<decimal?> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<decimal?> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<decimal?>, IObserver<decimal?>
+        internal sealed class _ : Sink<decimal?>, IObserver<decimal?>
         {
             private decimal? _lastValue;
 
@@ -671,7 +643,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class MinInt32Nullable : Producer<int?>
+    internal sealed class MinInt32Nullable : Producer<int?, MinInt32Nullable._>
     {
         private readonly IObservable<int?> _source;
 
@@ -680,14 +652,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<int?> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<int?> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<int?>, IObserver<int?>
+        internal sealed class _ : Sink<int?>, IObserver<int?>
         {
             private int? _lastValue;
 
@@ -730,7 +699,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class MinInt64Nullable : Producer<long?>
+    internal sealed class MinInt64Nullable : Producer<long?, MinInt64Nullable._>
     {
         private readonly IObservable<long?> _source;
 
@@ -739,14 +708,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<long?> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<long?> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<long?>, IObserver<long?>
+        internal sealed class _ : Sink<long?>, IObserver<long?>
         {
             private long? _lastValue;
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/MinBy.cs

@@ -6,7 +6,7 @@ using System.Collections.Generic;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class MinBy<TSource, TKey> : Producer<IList<TSource>>
+    internal sealed class MinBy<TSource, TKey> : Producer<IList<TSource>, MinBy<TSource, TKey>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly Func<TSource, TKey> _keySelector;
@@ -19,14 +19,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _comparer = comparer;
         }
 
-        protected override IDisposable Run(IObserver<IList<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(this, observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<IList<TSource>> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+        internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
         {
             private readonly MinBy<TSource, TKey> _parent;
             private bool _hasValue;

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Multicast.cs

@@ -7,7 +7,7 @@ using System.Reactive.Subjects;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Multicast<TSource, TIntermediate, TResult> : Producer<TResult>
+    internal sealed class Multicast<TSource, TIntermediate, TResult> : Producer<TResult, Multicast<TSource, TIntermediate, TResult>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly Func<ISubject<TSource, TIntermediate>> _subjectSelector;
@@ -20,14 +20,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _selector = selector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return sink.Run(this);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        private sealed class _ : Sink<TResult>, IObserver<TResult>
+        internal sealed class _ : Sink<TResult>, IObserver<TResult>
         {
             public _(IObserver<TResult> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/OfType.cs

@@ -4,7 +4,7 @@
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class OfType<TSource, TResult> : Producer<TResult>
+    internal sealed class OfType<TSource, TResult> : Producer<TResult, OfType<TSource, TResult>._>
     {
         private readonly IObservable<TSource> _source;
 
@@ -13,14 +13,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<TResult>, IObserver<TSource>
+        internal sealed class _ : Sink<TResult>, IObserver<TSource>
         {
             public _(IObserver<TResult> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/OnErrorResumeNext.cs

@@ -6,7 +6,7 @@ using System.Collections.Generic;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class OnErrorResumeNext<TSource> : Producer<TSource>
+    internal sealed class OnErrorResumeNext<TSource> : Producer<TSource, OnErrorResumeNext<TSource>._>
     {
         private readonly IEnumerable<IObservable<TSource>> _sources;
 
@@ -15,14 +15,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _sources = sources;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return sink.Run(_sources);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_sources);
 
-        private sealed class _ : TailRecursiveSink<TSource>
+        internal sealed class _ : TailRecursiveSink<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Range.cs

@@ -7,7 +7,7 @@ using System.Reactive.Disposables;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Range : Producer<int>
+    internal sealed class Range : Producer<int, Range._>
     {
         private readonly int _start;
         private readonly int _count;
@@ -20,14 +20,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _scheduler = scheduler;
         }
 
-        protected override IDisposable Run(IObserver<int> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(this, observer, cancel);
-            setSink(sink);
-            return sink.Run(_scheduler);
-        }
+        protected override _ CreateSink(IObserver<int> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_scheduler);
 
-        private sealed class _ : Sink<int>
+        internal sealed class _ : Sink<int>
         {
             private readonly int _start;
             private readonly int _count;

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/RefCount.cs

@@ -7,7 +7,7 @@ using System.Reactive.Subjects;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class RefCount<TSource> : Producer<TSource>
+    internal sealed class RefCount<TSource> : Producer<TSource, RefCount<TSource>._>
     {
         private readonly IConnectableObservable<TSource> _source;
 
@@ -23,14 +23,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _connectableSubscription = default(IDisposable);
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return sink.Run(this);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/Repeat.cs

@@ -9,7 +9,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class Repeat<TResult>
     {
-        internal sealed class Forever : Producer<TResult>
+        internal sealed class Forever : Producer<TResult, Forever._>
         {
             private readonly TResult _value;
             private readonly IScheduler _scheduler;
@@ -20,14 +20,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _scheduler = scheduler;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_value, observer, cancel);
-                setSink(sink);
-                return sink.Run(this);
-            }
+            protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_value, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            private sealed class _ : Sink<TResult>
+            internal sealed class _ : Sink<TResult>
             {
                 private readonly TResult _value;
 
@@ -67,7 +64,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Count : Producer<TResult>
+        internal sealed class Count : Producer<TResult, Count._>
         {
             private readonly TResult _value;
             private readonly IScheduler _scheduler;
@@ -80,14 +77,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _repeatCount = repeatCount;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_value, observer, cancel);
-                setSink(sink);
-                return sink.Run(this);
-            }
+            protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_value, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            private sealed class _ : Sink<TResult>
+            internal sealed class _ : Sink<TResult>
             {
                 private readonly TResult _value;
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Return.cs

@@ -6,7 +6,7 @@ using System.Reactive.Concurrency;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Return<TResult> : Producer<TResult>
+    internal sealed class Return<TResult> : Producer<TResult, Return<TResult>._>
     {
         private readonly TResult _value;
         private readonly IScheduler _scheduler;
@@ -17,14 +17,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _scheduler = scheduler;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_value, observer, cancel);
-            setSink(sink);
-            return sink.Run(_scheduler);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_value, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_scheduler);
 
-        private sealed class _ : Sink<TResult>
+        internal sealed class _ : Sink<TResult>
         {
             private readonly TResult _value;
 

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/Sample.cs

@@ -7,7 +7,7 @@ using System.Reactive.Disposables;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Sample<TSource, TSample> : Producer<TSource>
+    internal sealed class Sample<TSource, TSample> : Producer<TSource, Sample<TSource, TSample>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly IObservable<TSample> _sampler;
@@ -18,14 +18,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _sampler = sampler;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return sink.Run(this);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             private readonly object _gate = new object();
 
@@ -136,7 +133,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class Sample<TSource> : Producer<TSource>
+    internal sealed class Sample<TSource> : Producer<TSource, Sample<TSource>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly TimeSpan _interval;
@@ -149,14 +146,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _scheduler = scheduler;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return sink.Run(this);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             private object _gate = new object();
 

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/Scan.cs

@@ -4,7 +4,7 @@
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Scan<TSource, TAccumulate> : Producer<TAccumulate>
+    internal sealed class Scan<TSource, TAccumulate> : Producer<TAccumulate, Scan<TSource, TAccumulate>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly TAccumulate _seed;
@@ -17,14 +17,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _accumulator = accumulator;
         }
 
-        protected override IDisposable Run(IObserver<TAccumulate> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(this, observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<TAccumulate> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<TAccumulate>, IObserver<TSource>
+        internal sealed class _ : Sink<TAccumulate>, IObserver<TSource>
         {
             private readonly Func<TAccumulate, TSource, TAccumulate> _accumulator;
             private TAccumulate _accumulation;
@@ -66,7 +63,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class Scan<TSource> : Producer<TSource>
+    internal sealed class Scan<TSource> : Producer<TSource, Scan<TSource>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly Func<TSource, TSource, TSource> _accumulator;
@@ -77,14 +74,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _accumulator = accumulator;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_accumulator, observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_accumulator, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             private readonly Func<TSource, TSource, TSource> _accumulator;
             private TSource _accumulation;

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/Select.cs

@@ -6,7 +6,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class Select<TSource, TResult>
     {
-        internal sealed class Selector : Producer<TResult>
+        internal sealed class Selector : Producer<TResult, Selector._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, TResult> _selector;
@@ -17,14 +17,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _selector = selector;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_selector, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_selector, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TResult>, IObserver<TSource>
+            internal sealed class _ : Sink<TResult>, IObserver<TSource>
             {
                 private readonly Func<TSource, TResult> _selector;
 
@@ -65,7 +62,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class SelectorIndexed : Producer<TResult>
+        internal sealed class SelectorIndexed : Producer<TResult, SelectorIndexed._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, int, TResult> _selector;
@@ -76,14 +73,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _selector = selector;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_selector, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_selector, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TResult>, IObserver<TSource>
+            internal sealed class _ : Sink<TResult>, IObserver<TSource>
             {
                 private readonly Func<TSource, int, TResult> _selector;
                 private int _index;

+ 64 - 110
Rx.NET/Source/src/System.Reactive/Linq/Observable/SelectMany.cs

@@ -11,7 +11,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class SelectMany<TSource, TCollection, TResult>
     {
-        internal sealed class ObservableSelector : Producer<TResult>
+        internal sealed class ObservableSelector : Producer<TResult, ObservableSelector._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, IObservable<TCollection>> _collectionSelector;
@@ -24,14 +24,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _resultSelector = resultSelector;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run(_source);
-            }
+            protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-            private sealed class _ : Sink<TResult>, IObserver<TSource>
+            internal sealed class _ : Sink<TResult>, IObserver<TSource>
             {
                 private readonly object _gate = new object();
                 private readonly SingleAssignmentDisposable _sourceSubscription = new SingleAssignmentDisposable();
@@ -183,7 +180,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class ObservableSelectorIndexed : Producer<TResult>
+        internal sealed class ObservableSelectorIndexed : Producer<TResult, ObservableSelectorIndexed._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, int, IObservable<TCollection>> _collectionSelector;
@@ -196,14 +193,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _resultSelector = resultSelector;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run(_source);
-            }
+            protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(this, observer, cancel);
 
-            private sealed class _ : Sink<TResult>, IObserver<TSource>
+            protected override IDisposable Run(_ sink) => sink.Run(_source);
+
+            internal sealed class _ : Sink<TResult>, IObserver<TSource>
             {
                 private readonly object _gate = new object();
                 private readonly SingleAssignmentDisposable _sourceSubscription = new SingleAssignmentDisposable();
@@ -361,7 +355,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class EnumerableSelector : Producer<TResult>
+        internal sealed class EnumerableSelector : Producer<TResult, EnumerableSelector._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, IEnumerable<TCollection>> _collectionSelector;
@@ -374,14 +368,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _resultSelector = resultSelector;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(this, observer, cancel);
 
-            private sealed class _ : Sink<TResult>, IObserver<TSource>
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
+
+            internal sealed class _ : Sink<TResult>, IObserver<TSource>
             {
                 private readonly Func<TSource, IEnumerable<TCollection>> _collectionSelector;
                 private readonly Func<TSource, TCollection, TResult> _resultSelector;
@@ -465,7 +456,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class EnumerableSelectorIndexed : Producer<TResult>
+        internal sealed class EnumerableSelectorIndexed : Producer<TResult, EnumerableSelectorIndexed._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, int, IEnumerable<TCollection>> _collectionSelector;
@@ -478,14 +469,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _resultSelector = resultSelector;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TResult>, IObserver<TSource>
+            internal sealed class _ : Sink<TResult>, IObserver<TSource>
             {
                 private readonly Func<TSource, int, IEnumerable<TCollection>> _collectionSelector;
                 private readonly Func<TSource, int, TCollection, int, TResult> _resultSelector;
@@ -574,7 +562,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class TaskSelector : Producer<TResult>
+        internal sealed class TaskSelector : Producer<TResult, TaskSelector._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, CancellationToken, Task<TCollection>> _collectionSelector;
@@ -587,14 +575,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _resultSelector = resultSelector;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run(_source);
-            }
+            protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-            private sealed class _ : Sink<TResult>, IObserver<TSource>
+            internal sealed class _ : Sink<TResult>, IObserver<TSource>
             {
                 private readonly object _gate = new object();
                 private readonly CancellationDisposable _cancel = new CancellationDisposable();
@@ -730,7 +715,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class TaskSelectorIndexed : Producer<TResult>
+        internal sealed class TaskSelectorIndexed : Producer<TResult, TaskSelectorIndexed._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, int, CancellationToken, Task<TCollection>> _collectionSelector;
@@ -743,14 +728,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _resultSelector = resultSelector;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run(_source);
-            }
+            protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-            private sealed class _ : Sink<TResult>, IObserver<TSource>
+            internal sealed class _ : Sink<TResult>, IObserver<TSource>
             {
                 private readonly object _gate = new object();
                 private readonly CancellationDisposable _cancel = new CancellationDisposable();
@@ -892,7 +874,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
     internal static class SelectMany<TSource, TResult>
     {
-        internal class ObservableSelector : Producer<TResult>
+        internal class ObservableSelector : Producer<TResult, ObservableSelector._>
         {
             protected readonly IObservable<TSource> _source;
             protected readonly Func<TSource, IObservable<TResult>> _selector;
@@ -903,14 +885,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _selector = selector;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run(_source);
-            }
+            protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(this, observer, cancel);
 
-            protected class _ : Sink<TResult>, IObserver<TSource>
+            protected override IDisposable Run(_ sink) => sink.Run(_source);
+
+            internal class _ : Sink<TResult>, IObserver<TSource>
             {
                 protected readonly object _gate = new object();
                 private readonly SingleAssignmentDisposable _sourceSubscription = new SingleAssignmentDisposable();
@@ -1064,14 +1043,9 @@ namespace System.Reactive.Linq.ObservableImpl
                 _selectorOnCompleted = selectorOnCompleted;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run(_source);
-            }
+            protected override ObservableSelector._ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(this, observer, cancel);
 
-            new private sealed class _ : ObservableSelector._
+            new internal sealed class _ : ObservableSelector._
             {
                 private readonly Func<Exception, IObservable<TResult>> _selectorOnError;
                 private readonly Func<IObservable<TResult>> _selectorOnCompleted;
@@ -1141,7 +1115,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal class ObservableSelectorIndexed : Producer<TResult>
+        internal class ObservableSelectorIndexed : Producer<TResult, ObservableSelectorIndexed._>
         {
             protected readonly IObservable<TSource> _source;
             protected readonly Func<TSource, int, IObservable<TResult>> _selector;
@@ -1152,14 +1126,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _selector = selector;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run(_source);
-            }
+            protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(this, observer, cancel);
 
-            protected class _ : Sink<TResult>, IObserver<TSource>
+            protected override IDisposable Run(_ sink) => sink.Run(_source);
+
+            internal class _ : Sink<TResult>, IObserver<TSource>
             {
                 private readonly object _gate = new object();
                 private readonly SingleAssignmentDisposable _sourceSubscription = new SingleAssignmentDisposable();
@@ -1314,14 +1285,9 @@ namespace System.Reactive.Linq.ObservableImpl
                 _selectorOnCompleted = selectorOnCompleted;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run(_source);
-            }
+            protected override ObservableSelectorIndexed._ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(this, observer, cancel);
 
-            new private sealed class _ : ObservableSelectorIndexed._
+            new internal sealed class _ : ObservableSelectorIndexed._
             {
                 private readonly object _gate = new object();
                 private readonly SingleAssignmentDisposable _sourceSubscription = new SingleAssignmentDisposable();
@@ -1397,7 +1363,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class EnumerableSelector : Producer<TResult>
+        internal sealed class EnumerableSelector : Producer<TResult, EnumerableSelector._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, IEnumerable<TResult>> _selector;
@@ -1408,14 +1374,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _selector = selector;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(this, observer, cancel);
 
-            private sealed class _ : Sink<TResult>, IObserver<TSource>
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
+
+            internal sealed class _ : Sink<TResult>, IObserver<TSource>
             {
                 private readonly Func<TSource, IEnumerable<TResult>> _selector;
 
@@ -1497,7 +1460,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class EnumerableSelectorIndexed : Producer<TResult>
+        internal sealed class EnumerableSelectorIndexed : Producer<TResult, EnumerableSelectorIndexed._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, int, IEnumerable<TResult>> _selector;
@@ -1508,14 +1471,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _selector = selector;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(this, observer, cancel);
 
-            private sealed class _ : Sink<TResult>, IObserver<TSource>
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
+
+            internal sealed class _ : Sink<TResult>, IObserver<TSource>
             {
                 private readonly Func<TSource, int, IEnumerable<TResult>> _selector;
 
@@ -1599,7 +1559,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class TaskSelector : Producer<TResult>
+        internal sealed class TaskSelector : Producer<TResult, TaskSelector._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, CancellationToken, Task<TResult>> _selector;
@@ -1610,14 +1570,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _selector = selector;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run(_source);
-            }
+            protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-            private sealed class _ : Sink<TResult>, IObserver<TSource>
+            internal sealed class _ : Sink<TResult>, IObserver<TSource>
             {
                 private readonly object _gate = new object();
                 private readonly CancellationDisposable _cancel = new CancellationDisposable();
@@ -1727,7 +1684,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class TaskSelectorIndexed : Producer<TResult>
+        internal sealed class TaskSelectorIndexed : Producer<TResult, TaskSelectorIndexed._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, int, CancellationToken, Task<TResult>> _selector;
@@ -1738,14 +1695,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _selector = selector;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run(_source);
-            }
+            protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-            private sealed class _ : Sink<TResult>, IObserver<TSource>
+            internal sealed class _ : Sink<TResult>, IObserver<TSource>
             {
                 private readonly object _gate = new object();
                 private readonly CancellationDisposable _cancel = new CancellationDisposable();

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/SequenceEqual.cs

@@ -9,7 +9,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class SequenceEqual<TSource>
     {
-        internal sealed class Observable : Producer<bool>
+        internal sealed class Observable : Producer<bool, Observable._>
         {
             private readonly IObservable<TSource> _first;
             private readonly IObservable<TSource> _second;
@@ -22,14 +22,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _comparer = comparer;
             }
 
-            protected override IDisposable Run(IObserver<bool> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_comparer, observer, cancel);
-                setSink(sink);
-                return sink.Run(this);
-            }
+            protected override _ CreateSink(IObserver<bool> observer, IDisposable cancel) => new _(_comparer, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            private sealed class _ : Sink<bool>
+            internal sealed class _ : Sink<bool>
             {
                 private readonly IEqualityComparer<TSource> _comparer;
 
@@ -218,7 +215,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Enumerable : Producer<bool>
+        internal sealed class Enumerable : Producer<bool, Enumerable._>
         {
             private readonly IObservable<TSource> _first;
             private readonly IEnumerable<TSource> _second;
@@ -231,14 +228,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _comparer = comparer;
             }
 
-            protected override IDisposable Run(IObserver<bool> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_comparer, observer, cancel);
-                setSink(sink);
-                return sink.Run(this);
-            }
+            protected override _ CreateSink(IObserver<bool> observer, IDisposable cancel) => new _(_comparer, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            private sealed class _ : Sink<bool>, IObserver<TSource>
+            internal sealed class _ : Sink<bool>, IObserver<TSource>
             {
                 private readonly IEqualityComparer<TSource> _comparer;
 

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/SingleAsync.cs

@@ -6,7 +6,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class SingleAsync<TSource>
     {
-        internal sealed class Sequence : Producer<TSource>
+        internal sealed class Sequence : Producer<TSource, Sequence._>
         {
             private readonly IObservable<TSource> _source;
 
@@ -15,14 +15,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _source = source;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private TSource _value;
                 private bool _seenValue;
@@ -70,7 +67,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Predicate : Producer<TSource>
+        internal sealed class Predicate : Producer<TSource, Predicate._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, bool> _predicate;
@@ -81,14 +78,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _predicate = predicate;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_predicate, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_predicate, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private readonly Func<TSource, bool> _predicate;
                 private TSource _value;

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/SingleOrDefaultAsync.cs

@@ -6,7 +6,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class SingleOrDefaultAsync<TSource>
     {
-        internal sealed class Sequence : Producer<TSource>
+        internal sealed class Sequence : Producer<TSource, Sequence._>
         {
             private readonly IObservable<TSource> _source;
 
@@ -15,14 +15,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _source = source;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private TSource _value;
                 private bool _seenValue;
@@ -62,7 +59,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Predicate : Producer<TSource>
+        internal sealed class Predicate : Producer<TSource, Predicate._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, bool> _predicate;
@@ -73,14 +70,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _predicate = predicate;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_predicate, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_predicate, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private readonly Func<TSource, bool> _predicate;
                 private TSource _value;

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/Skip.cs

@@ -9,7 +9,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class Skip<TSource>
     {
-        internal sealed class Count : Producer<TSource>
+        internal sealed class Count : Producer<TSource, Count._>
         {
             private readonly IObservable<TSource> _source;
             private readonly int _count;
@@ -32,14 +32,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 return new Count(_source, _count + count);
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_count, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_count, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private int _remaining;
 
@@ -71,7 +68,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Time : Producer<TSource>
+        internal sealed class Time : Producer<TSource, Time._>
         {
             private readonly IObservable<TSource> _source;
             private readonly TimeSpan _duration;
@@ -101,14 +98,11 @@ namespace System.Reactive.Linq.ObservableImpl
                     return new Time(_source, duration, _scheduler);
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(observer, cancel);
-                setSink(sink);
-                return sink.Run(this);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private volatile bool _open;
 

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/SkipLast.cs

@@ -9,7 +9,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class SkipLast<TSource>
     {
-        internal sealed class Count : Producer<TSource>
+        internal sealed class Count : Producer<TSource, Count._>
         {
             private readonly IObservable<TSource> _source;
             private readonly int _count;
@@ -20,14 +20,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _count = count;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_count, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_count, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private int _count;
                 private Queue<TSource> _queue;
@@ -60,7 +57,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Time : Producer<TSource>
+        internal sealed class Time : Producer<TSource, Time._>
         {
             private readonly IObservable<TSource> _source;
             private readonly TimeSpan _duration;
@@ -73,14 +70,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _scheduler = scheduler;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_duration, observer, cancel);
-                setSink(sink);
-                return sink.Run(this);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_duration, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private readonly TimeSpan _duration;
                 private Queue<System.Reactive.TimeInterval<TSource>> _queue;

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/SkipUntil.cs

@@ -7,7 +7,7 @@ using System.Reactive.Disposables;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class SkipUntil<TSource, TOther> : Producer<TSource>
+    internal sealed class SkipUntil<TSource, TOther> : Producer<TSource, SkipUntil<TSource, TOther>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly IObservable<TOther> _other;
@@ -18,14 +18,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _other = other;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return sink.Run(this);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        private sealed class _ : Sink<TSource>
+        internal sealed class _ : Sink<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)
@@ -123,7 +120,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class SkipUntil<TSource> : Producer<TSource>
+    internal sealed class SkipUntil<TSource> : Producer<TSource, SkipUntil<TSource>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly DateTimeOffset _startTime;
@@ -153,14 +150,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 return new SkipUntil<TSource>(_source, startTime, _scheduler);
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return sink.Run(this);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             private volatile bool _open;
 

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/SkipWhile.cs

@@ -6,7 +6,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class SkipWhile<TSource>
     {
-        internal sealed class Predicate : Producer<TSource>
+        internal sealed class Predicate : Producer<TSource, Predicate._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, bool> _predicate;
@@ -17,14 +17,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _predicate = predicate;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_predicate, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_predicate, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private Func<TSource, bool> _predicate;
 
@@ -77,7 +74,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class PredicateIndexed : Producer<TSource>
+        internal sealed class PredicateIndexed : Producer<TSource, PredicateIndexed._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, int, bool> _predicate;
@@ -88,14 +85,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _predicate = predicate;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_predicate, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_predicate, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private Func<TSource, int, bool> _predicate;
                 private int _index;

+ 50 - 80
Rx.NET/Source/src/System.Reactive/Linq/Observable/Sum.cs

@@ -4,7 +4,7 @@
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class SumDouble : Producer<double>
+    internal sealed class SumDouble : Producer<double, SumDouble._>
     {
         private readonly IObservable<double> _source;
 
@@ -13,14 +13,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<double> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<double> observer, IDisposable cancel) => new _(observer, cancel);
 
-        private sealed class _ : Sink<double>, IObserver<double>
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
+
+        internal sealed class _ : Sink<double>, IObserver<double>
         {
             private double _sum;
 
@@ -50,7 +47,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class SumSingle : Producer<float>
+    internal sealed class SumSingle : Producer<float, SumSingle._>
     {
         private readonly IObservable<float> _source;
 
@@ -59,14 +56,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<float> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<float> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<float>, IObserver<float>
+        internal sealed class _ : Sink<float>, IObserver<float>
         {
             private double _sum; // This is what LINQ to Objects does!
 
@@ -96,7 +90,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class SumDecimal : Producer<decimal>
+    internal sealed class SumDecimal : Producer<decimal, SumDecimal._>
     {
         private readonly IObservable<decimal> _source;
 
@@ -105,14 +99,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<decimal> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<decimal> observer, IDisposable cancel) => new _(observer, cancel);
 
-        private sealed class _ : Sink<decimal>, IObserver<decimal>
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
+
+        internal sealed class _ : Sink<decimal>, IObserver<decimal>
         {
             private decimal _sum;
 
@@ -142,7 +133,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class SumInt32 : Producer<int>
+    internal sealed class SumInt32 : Producer<int, SumInt32._>
     {
         private readonly IObservable<int> _source;
 
@@ -151,14 +142,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<int> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<int> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<int>, IObserver<int>
+        internal sealed class _ : Sink<int>, IObserver<int>
         {
             private int _sum;
 
@@ -199,7 +187,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class SumInt64 : Producer<long>
+    internal sealed class SumInt64 : Producer<long, SumInt64._>
     {
         private readonly IObservable<long> _source;
 
@@ -208,14 +196,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<long> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<long> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<long>, IObserver<long>
+        internal sealed class _ : Sink<long>, IObserver<long>
         {
             private long _sum;
 
@@ -256,7 +241,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class SumDoubleNullable : Producer<double?>
+    internal sealed class SumDoubleNullable : Producer<double?, SumDoubleNullable._>
     {
         private readonly IObservable<double?> _source;
 
@@ -265,14 +250,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<double?> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<double?> observer, IDisposable cancel) => new _(observer, cancel);
 
-        private sealed class _ : Sink<double?>, IObserver<double?>
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
+
+        internal sealed class _ : Sink<double?>, IObserver<double?>
         {
             private double _sum;
 
@@ -303,7 +285,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class SumSingleNullable : Producer<float?>
+    internal sealed class SumSingleNullable : Producer<float?, SumSingleNullable._>
     {
         private readonly IObservable<float?> _source;
 
@@ -312,14 +294,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<float?> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<float?> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<float?>, IObserver<float?>
+        internal sealed class _ : Sink<float?>, IObserver<float?>
         {
             private double _sum; // This is what LINQ to Objects does!
 
@@ -350,7 +329,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class SumDecimalNullable : Producer<decimal?>
+    internal sealed class SumDecimalNullable : Producer<decimal?, SumDecimalNullable._>
     {
         private readonly IObservable<decimal?> _source;
 
@@ -359,14 +338,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<decimal?> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<decimal?> observer, IDisposable cancel) => new _(observer, cancel);
 
-        private sealed class _ : Sink<decimal?>, IObserver<decimal?>
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
+
+        internal sealed class _ : Sink<decimal?>, IObserver<decimal?>
         {
             private decimal _sum;
 
@@ -397,7 +373,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class SumInt32Nullable : Producer<int?>
+    internal sealed class SumInt32Nullable : Producer<int?, SumInt32Nullable._>
     {
         private readonly IObservable<int?> _source;
 
@@ -406,14 +382,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<int?> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<int?> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<int?>, IObserver<int?>
+        internal sealed class _ : Sink<int?>, IObserver<int?>
         {
             private int _sum;
 
@@ -455,7 +428,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class SumInt64Nullable : Producer<long?>
+    internal sealed class SumInt64Nullable : Producer<long?, SumInt64Nullable._>
     {
         private readonly IObservable<long?> _source;
 
@@ -464,14 +437,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<long?> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<long?> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<long?>, IObserver<long?>
+        internal sealed class _ : Sink<long?>, IObserver<long?>
         {
             private long _sum;
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Switch.cs

@@ -6,7 +6,7 @@ using System.Reactive.Disposables;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Switch<TSource> : Producer<TSource>
+    internal sealed class Switch<TSource> : Producer<TSource, Switch<TSource>._>
     {
         private readonly IObservable<IObservable<TSource>> _sources;
 
@@ -15,14 +15,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _sources = sources;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return sink.Run(this);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        private sealed class _ : Sink<TSource>, IObserver<IObservable<TSource>>
+        internal sealed class _ : Sink<TSource>, IObserver<IObservable<TSource>>
         {
             private readonly object _gate = new object();
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Synchronize.cs

@@ -4,7 +4,7 @@
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Synchronize<TSource> : Producer<TSource>
+    internal sealed class Synchronize<TSource> : Producer<TSource, Synchronize<TSource>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly object _gate;
@@ -20,14 +20,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_gate, observer, cancel);
-            setSink(sink);
-            return _source.Subscribe(sink);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_gate, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.Subscribe(sink);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             private readonly object _gate;
 

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/Take.cs

@@ -9,7 +9,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class Take<TSource>
     {
-        internal sealed class Count : Producer<TSource>
+        internal sealed class Count : Producer<TSource, Count._>
         {
             private readonly IObservable<TSource> _source;
             private readonly int _count;
@@ -35,14 +35,11 @@ namespace System.Reactive.Linq.ObservableImpl
                     return new Count(_source, count);
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_count, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_count, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private int _remaining;
 
@@ -81,7 +78,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Time : Producer<TSource>
+        internal sealed class Time : Producer<TSource, Time._>
         {
             private readonly IObservable<TSource> _source;
             private readonly TimeSpan _duration;
@@ -111,14 +108,11 @@ namespace System.Reactive.Linq.ObservableImpl
                     return new Time(_source, duration, _scheduler);
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(observer, cancel);
-                setSink(sink);
-                return sink.Run(this);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 public _(IObserver<TSource> observer, IDisposable cancel)
                     : base(observer, cancel)

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/TakeLast.cs

@@ -10,7 +10,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class TakeLast<TSource>
     {
-        internal sealed class Count : Producer<TSource>
+        internal sealed class Count : Producer<TSource, Count._>
         {
             private readonly IObservable<TSource> _source;
             private readonly int _count;
@@ -23,14 +23,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _loopScheduler = loopScheduler;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run();
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run();
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 // CONSIDER: This sink has a parent reference that can be considered for removal.
 
@@ -117,7 +114,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Time : Producer<TSource>
+        internal sealed class Time : Producer<TSource, Time._>
         {
             private readonly IObservable<TSource> _source;
             private readonly TimeSpan _duration;
@@ -132,14 +129,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _loopScheduler = loopScheduler;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run();
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run();
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 // CONSIDER: This sink has a parent reference that can be considered for removal.
 

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/TakeLastBuffer.cs

@@ -9,7 +9,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class TakeLastBuffer<TSource>
     {
-        internal sealed class Count : Producer<IList<TSource>>
+        internal sealed class Count : Producer<IList<TSource>, Count._>
         {
             private readonly IObservable<TSource> _source;
             private readonly int _count;
@@ -20,14 +20,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _count = count;
             }
 
-            protected override IDisposable Run(IObserver<IList<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_count, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<IList<TSource>> observer, IDisposable cancel) => new _(_count, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
             {
                 private readonly int _count;
                 private Queue<TSource> _queue;
@@ -65,7 +62,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Time : Producer<IList<TSource>>
+        internal sealed class Time : Producer<IList<TSource>, Time._>
         {
             private readonly IObservable<TSource> _source;
             private readonly TimeSpan _duration;
@@ -78,14 +75,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _scheduler = scheduler;
             }
 
-            protected override IDisposable Run(IObserver<IList<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_duration, observer, cancel);
-                setSink(sink);
-                return sink.Run(this);
-            }
+            protected override _ CreateSink(IObserver<IList<TSource>> observer, IDisposable cancel) => new _(_duration, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            private sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
             {
                 private readonly TimeSpan _duration;
                 private Queue<System.Reactive.TimeInterval<TSource>> _queue;

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/TakeUntil.cs

@@ -7,7 +7,7 @@ using System.Reactive.Disposables;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class TakeUntil<TSource, TOther> : Producer<TSource>
+    internal sealed class TakeUntil<TSource, TOther> : Producer<TSource, TakeUntil<TSource, TOther>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly IObservable<TOther> _other;
@@ -18,14 +18,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _other = other;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return sink.Run(this);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        private sealed class _ : Sink<TSource>
+        internal sealed class _ : Sink<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)
@@ -156,7 +153,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class TakeUntil<TSource> : Producer<TSource>
+    internal sealed class TakeUntil<TSource> : Producer<TSource, TakeUntil<TSource>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly DateTimeOffset _endTime;
@@ -186,14 +183,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 return new TakeUntil<TSource>(_source, endTime, _scheduler);
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return sink.Run(this);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             private readonly object _gate = new object();
 

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/TakeWhile.cs

@@ -6,7 +6,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class TakeWhile<TSource>
     {
-        internal sealed class Predicate : Producer<TSource>
+        internal sealed class Predicate : Producer<TSource, Predicate._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, bool> _predicate;
@@ -17,14 +17,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _predicate = predicate;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_predicate, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_predicate, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private readonly Func<TSource, bool> _predicate;
                 private bool _running;
@@ -77,7 +74,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class PredicateIndexed : Producer<TSource>
+        internal sealed class PredicateIndexed : Producer<TSource, PredicateIndexed._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, int, bool> _predicate;
@@ -88,14 +85,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _predicate = predicate;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_predicate, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_predicate, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private readonly Func<TSource, int, bool> _predicate;
                 private bool _running;

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/Throttle.cs

@@ -7,7 +7,7 @@ using System.Reactive.Disposables;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Throttle<TSource> : Producer<TSource>
+    internal sealed class Throttle<TSource> : Producer<TSource, Throttle<TSource>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly TimeSpan _dueTime;
@@ -20,14 +20,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _scheduler = scheduler;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(this, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             private readonly TimeSpan _dueTime;
             private readonly IScheduler _scheduler;
@@ -118,7 +115,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class Throttle<TSource, TThrottle> : Producer<TSource>
+    internal sealed class Throttle<TSource, TThrottle> : Producer<TSource, Throttle<TSource, TThrottle>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly Func<TSource, IObservable<TThrottle>> _throttleSelector;
@@ -129,14 +126,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _throttleSelector = throttleSelector;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(this, observer, cancel);
-            setSink(sink);
-            return sink.Run(this);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             private readonly Func<TSource, IObservable<TThrottle>> _throttleSelector;
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Throw.cs

@@ -6,7 +6,7 @@ using System.Reactive.Concurrency;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Throw<TResult> : Producer<TResult>
+    internal sealed class Throw<TResult> : Producer<TResult, Throw<TResult>._>
     {
         private readonly Exception _exception;
         private readonly IScheduler _scheduler;
@@ -17,14 +17,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _scheduler = scheduler;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_exception, observer, cancel);
-            setSink(sink);
-            return sink.Run(_scheduler);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_exception, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_scheduler);
 
-        private sealed class _ : Sink<TResult>
+        internal sealed class _ : Sink<TResult>
         {
             private readonly Exception _exception;
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/TimeInterval.cs

@@ -6,7 +6,7 @@ using System.Reactive.Concurrency;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class TimeInterval<TSource> : Producer<System.Reactive.TimeInterval<TSource>>
+    internal sealed class TimeInterval<TSource> : Producer<System.Reactive.TimeInterval<TSource>, TimeInterval<TSource>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly IScheduler _scheduler;
@@ -17,14 +17,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _scheduler = scheduler;
         }
 
-        protected override IDisposable Run(IObserver<System.Reactive.TimeInterval<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return sink.Run(this);
-        }
+        protected override _ CreateSink(IObserver<System.Reactive.TimeInterval<TSource>> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        private sealed class _ : Sink<System.Reactive.TimeInterval<TSource>>, IObserver<TSource>
+        internal sealed class _ : Sink<System.Reactive.TimeInterval<TSource>>, IObserver<TSource>
         {
             public _(IObserver<System.Reactive.TimeInterval<TSource>> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 15 - 24
Rx.NET/Source/src/System.Reactive/Linq/Observable/Timeout.cs

@@ -9,7 +9,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class Timeout<TSource>
     {
-        internal sealed class Relative : Producer<TSource>
+        internal sealed class Relative : Producer<TSource, Relative._>
         {
             private readonly IObservable<TSource> _source;
             private readonly TimeSpan _dueTime;
@@ -24,14 +24,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _scheduler = scheduler;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run(_source);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private readonly TimeSpan _dueTime;
                 private readonly IObservable<TSource> _other;
@@ -151,7 +148,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Absolute : Producer<TSource>
+        internal sealed class Absolute : Producer<TSource, Absolute._>
         {
             private readonly IObservable<TSource> _source;
             private readonly DateTimeOffset _dueTime;
@@ -166,14 +163,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _scheduler = scheduler;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_other, observer, cancel);
-                setSink(sink);
-                return sink.Run(this);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_other, observer, cancel);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            protected override IDisposable Run(_ sink) => sink.Run(this);
+
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private readonly IObservable<TSource> _other;
 
@@ -263,7 +257,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class Timeout<TSource, TTimeout> : Producer<TSource>
+    internal sealed class Timeout<TSource, TTimeout> : Producer<TSource, Timeout<TSource, TTimeout>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly IObservable<TTimeout> _firstTimeout;
@@ -278,14 +272,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _other = other;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(this, observer, cancel);
-            setSink(sink);
-            return sink.Run(this);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             private readonly Func<TSource, IObservable<TTimeout>> _timeoutSelector;
             private readonly IObservable<TSource> _other;

+ 16 - 28
Rx.NET/Source/src/System.Reactive/Linq/Observable/Timer.cs

@@ -10,7 +10,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class Timer
     {
-        internal abstract class Single : Producer<long>
+        internal abstract class Single : Producer<long, Single._>
         {
             private readonly IScheduler _scheduler;
 
@@ -29,12 +29,9 @@ namespace System.Reactive.Linq.ObservableImpl
                     _dueTime = dueTime;
                 }
 
-                protected override IDisposable Run(IObserver<long> observer, IDisposable cancel, Action<IDisposable> setSink)
-                {
-                    var sink = new _(observer, cancel);
-                    setSink(sink);
-                    return sink.Run(this, _dueTime);
-                }
+                protected override _ CreateSink(IObserver<long> observer, IDisposable cancel) => new _(observer, cancel);
+
+                protected override IDisposable Run(_ sink) => sink.Run(this, _dueTime);
             }
 
             internal sealed class Absolute : Single
@@ -47,15 +44,12 @@ namespace System.Reactive.Linq.ObservableImpl
                     _dueTime = dueTime;
                 }
 
-                protected override IDisposable Run(IObserver<long> observer, IDisposable cancel, Action<IDisposable> setSink)
-                {
-                    var sink = new _(observer, cancel);
-                    setSink(sink);
-                    return sink.Run(this, _dueTime);
-                }
+                protected override _ CreateSink(IObserver<long> observer, IDisposable cancel) => new _(observer, cancel);
+
+                protected override IDisposable Run(_ sink) => sink.Run(this, _dueTime);
             }
 
-            private sealed class _ : Sink<long>
+            internal sealed class _ : Sink<long>
             {
                 public _(IObserver<long> observer, IDisposable cancel)
                     : base(observer, cancel)
@@ -81,7 +75,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal abstract class Periodic : Producer<long>
+        internal abstract class Periodic : Producer<long, Periodic._>
         {
             private readonly TimeSpan _period;
             private readonly IScheduler _scheduler;
@@ -102,12 +96,9 @@ namespace System.Reactive.Linq.ObservableImpl
                     _dueTime = dueTime;
                 }
 
-                protected override IDisposable Run(IObserver<long> observer, IDisposable cancel, Action<IDisposable> setSink)
-                {
-                    var sink = new _(_period, observer, cancel);
-                    setSink(sink);
-                    return sink.Run(this, _dueTime);
-                }
+                protected override _ CreateSink(IObserver<long> observer, IDisposable cancel) => new _(_period, observer, cancel);
+
+                protected override IDisposable Run(_ sink) => sink.Run(this, _dueTime);
             }
 
             internal sealed class Absolute : Periodic
@@ -120,15 +111,12 @@ namespace System.Reactive.Linq.ObservableImpl
                     _dueTime = dueTime;
                 }
 
-                protected override IDisposable Run(IObserver<long> observer, IDisposable cancel, Action<IDisposable> setSink)
-                {
-                    var sink = new _(_period, observer, cancel);
-                    setSink(sink);
-                    return sink.Run(this, _dueTime);
-                }
+                protected override _ CreateSink(IObserver<long> observer, IDisposable cancel) => new _(_period, observer, cancel);
+
+                protected override IDisposable Run(_ sink) => sink.Run(this, _dueTime);
             }
 
-            private sealed class _ : Sink<long>
+            internal sealed class _ : Sink<long>
             {
                 private readonly TimeSpan _period;
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Timestamp.cs

@@ -6,7 +6,7 @@ using System.Reactive.Concurrency;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Timestamp<TSource> : Producer<Timestamped<TSource>>
+    internal sealed class Timestamp<TSource> : Producer<Timestamped<TSource>, Timestamp<TSource>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly IScheduler _scheduler;
@@ -17,14 +17,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _scheduler = scheduler;
         }
 
-        protected override IDisposable Run(IObserver<Timestamped<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_scheduler, observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<Timestamped<TSource>> observer, IDisposable cancel) => new _(_scheduler, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<Timestamped<TSource>>, IObserver<TSource>
+        internal sealed class _ : Sink<Timestamped<TSource>>, IObserver<TSource>
         {
             private readonly IScheduler _scheduler;
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/ToArray.cs

@@ -6,7 +6,7 @@ using System.Collections.Generic;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class ToArray<TSource> : Producer<TSource[]>
+    internal sealed class ToArray<TSource> : Producer<TSource[], ToArray<TSource>._>
     {
         private readonly IObservable<TSource> _source;
 
@@ -15,14 +15,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<TSource[]> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<TSource[]> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<TSource[]>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource[]>, IObserver<TSource>
         {
             private readonly List<TSource> _list;
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/ToDictionary.cs

@@ -6,7 +6,7 @@ using System.Collections.Generic;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class ToDictionary<TSource, TKey, TElement> : Producer<IDictionary<TKey, TElement>>
+    internal sealed class ToDictionary<TSource, TKey, TElement> : Producer<IDictionary<TKey, TElement>, ToDictionary<TSource, TKey, TElement>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly Func<TSource, TKey> _keySelector;
@@ -21,14 +21,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _comparer = comparer;
         }
 
-        protected override IDisposable Run(IObserver<IDictionary<TKey, TElement>> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(this, observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<IDictionary<TKey, TElement>> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<IDictionary<TKey, TElement>>, IObserver<TSource>
+        internal sealed class _ : Sink<IDictionary<TKey, TElement>>, IObserver<TSource>
         {
             private readonly Func<TSource, TKey> _keySelector;
             private readonly Func<TSource, TElement> _elementSelector;

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/ToList.cs

@@ -6,7 +6,7 @@ using System.Collections.Generic;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class ToList<TSource> : Producer<IList<TSource>>
+    internal sealed class ToList<TSource> : Producer<IList<TSource>, ToList<TSource>._>
     {
         private readonly IObservable<TSource> _source;
 
@@ -15,14 +15,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<IList<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<IList<TSource>> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
+        internal sealed class _ : Sink<IList<TSource>>, IObserver<TSource>
         {
             private readonly List<TSource> _list;
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/ToLookup.cs

@@ -7,7 +7,7 @@ using System.Linq;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class ToLookup<TSource, TKey, TElement> : Producer<ILookup<TKey, TElement>>
+    internal sealed class ToLookup<TSource, TKey, TElement> : Producer<ILookup<TKey, TElement>, ToLookup<TSource, TKey, TElement>._>
     {
         private readonly IObservable<TSource> _source;
         private readonly Func<TSource, TKey> _keySelector;
@@ -22,14 +22,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _comparer = comparer;
         }
 
-        protected override IDisposable Run(IObserver<ILookup<TKey, TElement>> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(this, observer, cancel);
-            setSink(sink);
-            return _source.SubscribeSafe(sink);
-        }
+        protected override _ CreateSink(IObserver<ILookup<TKey, TElement>> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-        private sealed class _ : Sink<ILookup<TKey, TElement>>, IObserver<TSource>
+        internal sealed class _ : Sink<ILookup<TKey, TElement>>, IObserver<TSource>
         {
             private readonly Func<TSource, TKey> _keySelector;
             private readonly Func<TSource, TElement> _elementSelector;

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/ToObservable.cs

@@ -8,7 +8,7 @@ using System.Reactive.Disposables;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class ToObservable<TSource> : Producer<TSource>
+    internal sealed class ToObservable<TSource> : Producer<TSource, ToObservable<TSource>._>
     {
         private readonly IEnumerable<TSource> _source;
         private readonly IScheduler _scheduler;
@@ -19,14 +19,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _scheduler = scheduler;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return sink.Run(this);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        private sealed class _ : Sink<TSource>
+        internal sealed class _ : Sink<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Using.cs

@@ -6,7 +6,7 @@ using System.Reactive.Disposables;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class Using<TSource, TResource> : Producer<TSource>
+    internal sealed class Using<TSource, TResource> : Producer<TSource, Using<TSource, TResource>._>
         where TResource : IDisposable
     {
         private readonly Func<TResource> _resourceFactory;
@@ -18,14 +18,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _observableFactory = observableFactory;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return sink.Run(this);
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(this);
 
-        private sealed class _ : Sink<TSource>, IObserver<TSource>
+        internal sealed class _ : Sink<TSource>, IObserver<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 10 - 16
Rx.NET/Source/src/System.Reactive/Linq/Observable/Where.cs

@@ -6,7 +6,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class Where<TSource>
     {
-        internal sealed class Predicate : Producer<TSource>
+        internal sealed class Predicate : Producer<TSource, Predicate._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, bool> _predicate;
@@ -22,14 +22,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 return new Predicate(_source, x => _predicate(x) && predicate(x));
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_predicate, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_predicate, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private readonly Func<TSource, bool> _predicate;
 
@@ -73,7 +70,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class PredicateIndexed : Producer<TSource>
+        internal sealed class PredicateIndexed : Producer<TSource, PredicateIndexed._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<TSource, int, bool> _predicate;
@@ -84,14 +81,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _predicate = predicate;
             }
 
-            protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_predicate, observer, cancel);
-                setSink(sink);
-                return _source.SubscribeSafe(sink);
-            }
+            protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(_predicate, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => _source.SubscribeSafe(sink);
 
-            private sealed class _ : Sink<TSource>, IObserver<TSource>
+            internal sealed class _ : Sink<TSource>, IObserver<TSource>
             {
                 private readonly Func<TSource, int, bool> _predicate;
                 private int _index;

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/While.cs

@@ -6,7 +6,7 @@ using System.Collections.Generic;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class While<TSource> : Producer<TSource>, IConcatenatable<TSource>
+    internal sealed class While<TSource> : Producer<TSource, While<TSource>._>, IConcatenatable<TSource>
     {
         private readonly Func<bool> _condition;
         private readonly IObservable<TSource> _source;
@@ -17,12 +17,9 @@ namespace System.Reactive.Linq.ObservableImpl
             _source = source;
         }
 
-        protected override IDisposable Run(IObserver<TSource> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(observer, cancel);
-            setSink(sink);
-            return sink.Run(GetSources());
-        }
+        protected override _ CreateSink(IObserver<TSource> observer, IDisposable cancel) => new _(observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(GetSources());
 
         public IEnumerable<IObservable<TSource>> GetSources()
         {
@@ -30,7 +27,7 @@ namespace System.Reactive.Linq.ObservableImpl
                 yield return _source;
         }
 
-        private sealed class _ : ConcatSink<TSource>
+        internal sealed class _ : ConcatSink<TSource>
         {
             public _(IObserver<TSource> observer, IDisposable cancel)
                 : base(observer, cancel)

+ 30 - 48
Rx.NET/Source/src/System.Reactive/Linq/Observable/Window.cs

@@ -11,7 +11,7 @@ namespace System.Reactive.Linq.ObservableImpl
 {
     internal static class Window<TSource>
     {
-        internal sealed class Count : Producer<IObservable<TSource>>
+        internal sealed class Count : Producer<IObservable<TSource>, Count._>
         {
             private readonly IObservable<TSource> _source;
             private readonly int _count;
@@ -24,14 +24,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _skip = skip;
             }
 
-            protected override IDisposable Run(IObserver<IObservable<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run(_source);
-            }
+            protected override _ CreateSink(IObserver<IObservable<TSource>> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-            private sealed class _ : Sink<IObservable<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<IObservable<TSource>>, IObserver<TSource>
             {
                 private readonly Queue<ISubject<TSource>> _queue = new Queue<ISubject<TSource>>();
                 private readonly SingleAssignmentDisposable _m = new SingleAssignmentDisposable();
@@ -110,7 +107,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class TimeSliding : Producer<IObservable<TSource>>
+        internal sealed class TimeSliding : Producer<IObservable<TSource>, TimeSliding._>
         {
             private readonly IObservable<TSource> _source;
             private readonly TimeSpan _timeSpan;
@@ -125,14 +122,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _scheduler = scheduler;
             }
 
-            protected override IDisposable Run(IObserver<IObservable<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run(this);
-            }
+            protected override _ CreateSink(IObserver<IObservable<TSource>> observer, IDisposable cancel) => new _(this, observer, cancel);
 
-            private sealed class _ : Sink<IObservable<TSource>>, IObserver<TSource>
+            protected override IDisposable Run(_ sink) => sink.Run(this);
+
+            internal sealed class _ : Sink<IObservable<TSource>>, IObserver<TSource>
             {
                 private readonly object _gate = new object();
                 private readonly Queue<ISubject<TSource>> _q = new Queue<ISubject<TSource>>();
@@ -274,7 +268,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class TimeHopping : Producer<IObservable<TSource>>
+        internal sealed class TimeHopping : Producer<IObservable<TSource>, TimeHopping._>
         {
             private readonly IObservable<TSource> _source;
             private readonly TimeSpan _timeSpan;
@@ -287,14 +281,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _scheduler = scheduler;
             }
 
-            protected override IDisposable Run(IObserver<IObservable<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(observer, cancel);
-                setSink(sink);
-                return sink.Run(this);
-            }
+            protected override _ CreateSink(IObserver<IObservable<TSource>> observer, IDisposable cancel) => new _(observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            private sealed class _ : Sink<IObservable<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<IObservable<TSource>>, IObserver<TSource>
             {
                 private readonly object _gate = new object();
 
@@ -366,7 +357,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Ferry : Producer<IObservable<TSource>>
+        internal sealed class Ferry : Producer<IObservable<TSource>, Ferry._>
         {
             private readonly IObservable<TSource> _source;
             private readonly int _count;
@@ -381,14 +372,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _scheduler = scheduler;
             }
 
-            protected override IDisposable Run(IObserver<IObservable<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run(_source);
-            }
+            protected override _ CreateSink(IObserver<IObservable<TSource>> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(_source);
 
-            private sealed class _ : Sink<IObservable<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<IObservable<TSource>>, IObserver<TSource>
             {
                 private readonly object _gate = new object();
                 private readonly SerialDisposable _timerD = new SerialDisposable();
@@ -506,7 +494,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
     internal static class Window<TSource, TWindowClosing>
     {
-        internal sealed class Selector : Producer<IObservable<TSource>>
+        internal sealed class Selector : Producer<IObservable<TSource>, Selector._>
         {
             private readonly IObservable<TSource> _source;
             private readonly Func<IObservable<TWindowClosing>> _windowClosingSelector;
@@ -517,14 +505,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _windowClosingSelector = windowClosingSelector;
             }
 
-            protected override IDisposable Run(IObserver<IObservable<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run(_source);
-            }
+            protected override _ CreateSink(IObserver<IObservable<TSource>> observer, IDisposable cancel) => new _(this, observer, cancel);
 
-            private sealed class _ : Sink<IObservable<TSource>>, IObserver<TSource>
+            protected override IDisposable Run(_ sink) => sink.Run(_source);
+
+            internal sealed class _ : Sink<IObservable<TSource>>, IObserver<TSource>
             {
                 private readonly object _gate = new object();
                 private readonly AsyncLock _windowGate = new AsyncLock();
@@ -653,7 +638,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Boundaries : Producer<IObservable<TSource>>
+        internal sealed class Boundaries : Producer<IObservable<TSource>, Boundaries._>
         {
             private readonly IObservable<TSource> _source;
             private readonly IObservable<TWindowClosing> _windowBoundaries;
@@ -664,14 +649,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _windowBoundaries = windowBoundaries;
             }
 
-            protected override IDisposable Run(IObserver<IObservable<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(this, observer, cancel);
-                setSink(sink);
-                return sink.Run(this);
-            }
+            protected override _ CreateSink(IObserver<IObservable<TSource>> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(this);
 
-            private sealed class _ : Sink<IObservable<TSource>>, IObserver<TSource>
+            internal sealed class _ : Sink<IObservable<TSource>>, IObserver<TSource>
             {
                 private readonly object _gate = new object();
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/WithLatestFrom.cs

@@ -6,7 +6,7 @@ using System.Reactive.Disposables;
 
 namespace System.Reactive.Linq.ObservableImpl
 {
-    internal sealed class WithLatestFrom<TFirst, TSecond, TResult> : Producer<TResult>
+    internal sealed class WithLatestFrom<TFirst, TSecond, TResult> : Producer<TResult, WithLatestFrom<TFirst, TSecond, TResult>._>
     {
         private readonly IObservable<TFirst> _first;
         private readonly IObservable<TSecond> _second;
@@ -19,14 +19,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_first, _second);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_first, _second);
 
-        private sealed class _ : Sink<TResult>
+        internal sealed class _ : Sink<TResult>
         {
             private readonly Func<TFirst, TSecond, TResult> _resultSelector;
 

+ 71 - 113
Rx.NET/Source/src/System.Reactive/Linq/Observable/Zip.Generated.cs

@@ -10,9 +10,9 @@ namespace System.Reactive.Linq.ObservableImpl
 
     /* The following code is generated by a T4 template. */
 
-    #region Zip auto-generated code (4/17/2017 4:46:17 PM)
+    #region Zip auto-generated code (4/21/2017 10:40:30 AM)
 
-    internal sealed class Zip<T1, T2, T3, TResult> : Producer<TResult>
+    internal sealed class Zip<T1, T2, T3, TResult> : Producer<TResult, Zip<T1, T2, T3, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -27,14 +27,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3);
 
-        private sealed class _ : ZipSink<TResult>
+        internal sealed class _ : ZipSink<TResult>
         {
             private readonly Func<T1, T2, T3, TResult> _resultSelector;
 
@@ -85,7 +82,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class Zip<T1, T2, T3, T4, TResult> : Producer<TResult>
+    internal sealed class Zip<T1, T2, T3, T4, TResult> : Producer<TResult, Zip<T1, T2, T3, T4, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -102,14 +99,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4);
 
-        private sealed class _ : ZipSink<TResult>
+        internal sealed class _ : ZipSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, TResult> _resultSelector;
 
@@ -168,7 +162,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class Zip<T1, T2, T3, T4, T5, TResult> : Producer<TResult>
+    internal sealed class Zip<T1, T2, T3, T4, T5, TResult> : Producer<TResult, Zip<T1, T2, T3, T4, T5, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -187,14 +181,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5);
 
-        private sealed class _ : ZipSink<TResult>
+        internal sealed class _ : ZipSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, TResult> _resultSelector;
 
@@ -261,7 +252,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class Zip<T1, T2, T3, T4, T5, T6, TResult> : Producer<TResult>
+    internal sealed class Zip<T1, T2, T3, T4, T5, T6, TResult> : Producer<TResult, Zip<T1, T2, T3, T4, T5, T6, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -282,14 +273,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
 
-        private sealed class _ : ZipSink<TResult>
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6);
+
+        internal sealed class _ : ZipSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, TResult> _resultSelector;
 
@@ -364,7 +352,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class Zip<T1, T2, T3, T4, T5, T6, T7, TResult> : Producer<TResult>
+    internal sealed class Zip<T1, T2, T3, T4, T5, T6, T7, TResult> : Producer<TResult, Zip<T1, T2, T3, T4, T5, T6, T7, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -387,14 +375,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
 
-        private sealed class _ : ZipSink<TResult>
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7);
+
+        internal sealed class _ : ZipSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, T7, TResult> _resultSelector;
 
@@ -477,7 +462,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class Zip<T1, T2, T3, T4, T5, T6, T7, T8, TResult> : Producer<TResult>
+    internal sealed class Zip<T1, T2, T3, T4, T5, T6, T7, T8, TResult> : Producer<TResult, Zip<T1, T2, T3, T4, T5, T6, T7, T8, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -502,14 +487,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8);
 
-        private sealed class _ : ZipSink<TResult>
+        internal sealed class _ : ZipSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult> _resultSelector;
 
@@ -600,7 +582,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> : Producer<TResult>
+    internal sealed class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> : Producer<TResult, Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -627,14 +609,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9);
 
-        private sealed class _ : ZipSink<TResult>
+        internal sealed class _ : ZipSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> _resultSelector;
 
@@ -733,7 +712,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> : Producer<TResult>
+    internal sealed class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> : Producer<TResult, Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -762,14 +741,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10);
 
-        private sealed class _ : ZipSink<TResult>
+        internal sealed class _ : ZipSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> _resultSelector;
 
@@ -876,7 +852,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> : Producer<TResult>
+    internal sealed class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> : Producer<TResult, Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -907,14 +883,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11);
 
-        private sealed class _ : ZipSink<TResult>
+        internal sealed class _ : ZipSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> _resultSelector;
 
@@ -1029,7 +1002,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> : Producer<TResult>
+    internal sealed class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> : Producer<TResult, Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -1062,14 +1035,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11, _source12);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11, _source12);
 
-        private sealed class _ : ZipSink<TResult>
+        internal sealed class _ : ZipSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> _resultSelector;
 
@@ -1192,7 +1162,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> : Producer<TResult>
+    internal sealed class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> : Producer<TResult, Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -1227,14 +1197,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11, _source12, _source13);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
 
-        private sealed class _ : ZipSink<TResult>
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11, _source12, _source13);
+
+        internal sealed class _ : ZipSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> _resultSelector;
 
@@ -1365,7 +1332,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> : Producer<TResult>
+    internal sealed class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> : Producer<TResult, Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -1402,14 +1369,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11, _source12, _source13, _source14);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
 
-        private sealed class _ : ZipSink<TResult>
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11, _source12, _source13, _source14);
+
+        internal sealed class _ : ZipSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> _resultSelector;
 
@@ -1548,7 +1512,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> : Producer<TResult>
+    internal sealed class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> : Producer<TResult, Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -1587,14 +1551,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11, _source12, _source13, _source14, _source15);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11, _source12, _source13, _source14, _source15);
 
-        private sealed class _ : ZipSink<TResult>
+        internal sealed class _ : ZipSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> _resultSelector;
 
@@ -1741,7 +1702,7 @@ namespace System.Reactive.Linq.ObservableImpl
         }
     }
 
-    internal sealed class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> : Producer<TResult>
+    internal sealed class Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> : Producer<TResult, Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult>._>
     {
         private readonly IObservable<T1> _source1;
         private readonly IObservable<T2> _source2;
@@ -1782,14 +1743,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11, _source12, _source13, _source14, _source15, _source16);
-        }
+        protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(_source1, _source2, _source3, _source4, _source5, _source6, _source7, _source8, _source9, _source10, _source11, _source12, _source13, _source14, _source15, _source16);
 
-        private sealed class _ : ZipSink<TResult>
+        internal sealed class _ : ZipSink<TResult>
         {
             private readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult> _resultSelector;
 

+ 5 - 8
Rx.NET/Source/src/System.Reactive/Linq/Observable/Zip.Generated.tt

@@ -26,7 +26,7 @@ for (var i = 3; i <= 16; i++)
     var vs = string.Join(", ", Enumerable.Range(1, i).Select(j => "_observer" + j + ".Values.Dequeue()"));
     var ss = string.Join(", ", Enumerable.Range(1, i).Select(j => "_source" + j));
 #>
-    internal sealed class Zip<<#=ts#>, TResult> : Producer<TResult>
+    internal sealed class Zip<<#=ts#>, TResult> : Producer<TResult, Zip<<#=ts#>, TResult>._>
     {
 <#
 for (var j = 1; j <= i; j++)
@@ -51,14 +51,11 @@ for (var j = 1; j <= i; j++)
             _resultSelector = resultSelector;
         }
 
-        protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(_resultSelector, observer, cancel);
-            setSink(sink);
-            return sink.Run(<#=ss#>);
-        }
+        protected override _ CreateSink2(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run(<#=ss#>);
 
-        private sealed class _ : ZipSink<TResult>
+        internal sealed class _ : ZipSink<TResult>
         {
             private readonly Func<<#=ts#>, TResult> _resultSelector;
 

+ 15 - 24
Rx.NET/Source/src/System.Reactive/Linq/Observable/Zip.cs

@@ -13,7 +13,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
     internal static class Zip<TFirst, TSecond, TResult>
     {
-        internal sealed class Observable : Producer<TResult>
+        internal sealed class Observable : Producer<TResult, Observable._>
         {
             private readonly IObservable<TFirst> _first;
             private readonly IObservable<TSecond> _second;
@@ -26,14 +26,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _resultSelector = resultSelector;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_resultSelector, observer, cancel);
-                setSink(sink);
-                return sink.Run(_first, _second);
-            }
+            protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
+
+            protected override IDisposable Run(_ sink) => sink.Run(_first, _second);
 
-            private sealed class _ : Sink<TResult>
+            internal sealed class _ : Sink<TResult>
             {
                 private readonly Func<TFirst, TSecond, TResult> _resultSelector;
 
@@ -244,7 +241,7 @@ namespace System.Reactive.Linq.ObservableImpl
             }
         }
 
-        internal sealed class Enumerable : Producer<TResult>
+        internal sealed class Enumerable : Producer<TResult, Enumerable._>
         {
             private readonly IObservable<TFirst> _first;
             private readonly IEnumerable<TSecond> _second;
@@ -257,14 +254,11 @@ namespace System.Reactive.Linq.ObservableImpl
                 _resultSelector = resultSelector;
             }
 
-            protected override IDisposable Run(IObserver<TResult> observer, IDisposable cancel, Action<IDisposable> setSink)
-            {
-                var sink = new _(_resultSelector, observer, cancel);
-                setSink(sink);
-                return sink.Run(_first, _second);
-            }
+            protected override _ CreateSink(IObserver<TResult> observer, IDisposable cancel) => new _(_resultSelector, observer, cancel);
 
-            private sealed class _ : Sink<TResult>, IObserver<TFirst>
+            protected override IDisposable Run(_ sink) => sink.Run(_first, _second);
+
+            internal sealed class _ : Sink<TResult>, IObserver<TFirst>
             {
                 private readonly Func<TFirst, TSecond, TResult> _resultSelector;
 
@@ -530,7 +524,7 @@ namespace System.Reactive.Linq.ObservableImpl
 
     #region N-ary
 
-    internal sealed class Zip<TSource> : Producer<IList<TSource>>
+    internal sealed class Zip<TSource> : Producer<IList<TSource>, Zip<TSource>._>
     {
         private readonly IEnumerable<IObservable<TSource>> _sources;
 
@@ -539,14 +533,11 @@ namespace System.Reactive.Linq.ObservableImpl
             _sources = sources;
         }
 
-        protected override IDisposable Run(IObserver<IList<TSource>> observer, IDisposable cancel, Action<IDisposable> setSink)
-        {
-            var sink = new _(this, observer, cancel);
-            setSink(sink);
-            return sink.Run();
-        }
+        protected override _ CreateSink(IObserver<IList<TSource>> observer, IDisposable cancel) => new _(this, observer, cancel);
+
+        protected override IDisposable Run(_ sink) => sink.Run();
 
-        private sealed class _ : Sink<IList<TSource>>
+        internal sealed class _ : Sink<IList<TSource>>
         {
             private readonly Zip<TSource> _parent;