dotnet / dotnet/reactive

Inconsistent behaviour: CombineLatest-completion with no sources

Open
#1,791 4 comments 2 reactions 0 assignees View on GitHub
[area] Rx
Dominant language
C#
Stars
7.2k
Forks
798
PR merge metrics
No merged PRs in 30d

Description

I would consider this more of an improvement potential but it could also be seen as a bug.
While analysing the exact behaviour of the following extension I noticed a behaviour which is inconsistent in my opinion. I think this could possibly lead to unexpected subscription leaks in certain use cases.

This regards the extension-method
```csharp
IObservable> CombineLatest(this IEnumerable> sources)
```
within _System.Reactive.Linq.Observable_.

1. When the sources are empty the resulting observable does never complete. I find this odd because technically all the sources are complete since there are none.

2. In contrast if the sources are an array with a single observable that eventually completes, once it does the resulting observable will complete as well.

My expectation:
When the sources are empty the resulting observable completes right away.

> Which library version?
5.0.0

> Do you have a code snippet or project that reproduces the problem?
To following unit tests ordered the same as the points 1. and 2. above, reproduce the behaviour the way I described it. This only describes the current state and not my expectation.

```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using System.Reactive.Linq;
using Moq;
using NUnit.Framework;

namespace CosmicShores.Tests.Core.Rx {
[TestFixture]
public class ObservableTests {
[Test]
public void EmptyObservableEnumerable_CombineLatest_NoObserverMethodIsCalled() {
var observer = new Mock>>(MockBehavior.Strict);
var observable = Enumerable.Empty>().CombineLatest();
Assert.DoesNotThrow(() => observable.Subscribe(observer.Object));
}

[Test]
public void ObservableEnumerableWithSingleEntry_CombineLatest_Completes() {
var observable = new[] { Observable.Return(Unit.Default) }.CombineLatest();
var completeCalled = false;
observable.Subscribe(_ => { }, _ => { }, () => completeCalled = true);
Assert.True(completeCalled, "Complete was never called");
}
}
}
```

Changing this could technically be a breaking change to some people so it would have to be released in a new mayor version.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.