Skip to content

Commit

Permalink
Fix shared state issue in List.Transform. Fixes #618 (#619)
Browse files Browse the repository at this point in the history
  • Loading branch information
RolandPheasant authored Jul 19, 2022
1 parent fcb0217 commit ba8d3c8
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 24 deletions.
18 changes: 18 additions & 0 deletions src/DynamicData.Tests/List/TransformFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,22 @@ public void Update()
_results.Messages[0].Adds.Should().Be(1, "Should be 1 adds");
_results.Messages[0].Replaced.Should().Be(0, "Should be 1 update");
}


[Fact]
public void MultipleSubscribersShouldNotShareState()
{
_source.AddRange(new Person[]
{
new ("Adult1", 50),
new ("Adult2", 51)
});

var transformed = _source.Connect()
.Transform(o => o);

// will throw if state of ChangeAwareList is shared
transformed.Transform(o => o).Subscribe();
transformed.Transform(o => o).Subscribe();
}
}
4 changes: 0 additions & 4 deletions src/DynamicData/List/Internal/TransformAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,8 @@
// Roland Pheasant licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Reactive.Threading.Tasks;
using System.Threading.Tasks;

namespace DynamicData.List.Internal;

Expand Down
3 changes: 0 additions & 3 deletions src/DynamicData/List/Internal/TransformMany.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@
// Roland Pheasant licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Linq;

Expand Down
24 changes: 7 additions & 17 deletions src/DynamicData/List/Internal/Transformer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ public Transformer(IObservable<IChangeSet<TSource>> source, Func<TSource, Option
_containerFactory = (item, prev, index) => new TransformedItemContainer(item, factory(item, prev, index));
}

public IObservable<IChangeSet<TDestination>> Run()
{
return _source.Scan(new ChangeAwareList<TransformedItemContainer>(), (state, changes) =>
public IObservable<IChangeSet<TDestination>> Run() => Observable.Defer(RunImpl);

private IObservable<IChangeSet<TDestination>> RunImpl() => _source.Scan(new ChangeAwareList<TransformedItemContainer>(), (state, changes) =>
{
Transform(state, changes);
return state;
Expand All @@ -43,7 +43,6 @@ public IObservable<IChangeSet<TDestination>> Run()
var changed = transformed.CaptureChanges();
return changed.Transform(container => container.Destination);
});
}

private void Transform(ChangeAwareList<TransformedItemContainer> transformed, IChangeSet<TSource> changes)
{
Expand Down Expand Up @@ -125,7 +124,7 @@ private void Transform(ChangeAwareList<TransformedItemContainer> transformed, IC
}
else
{
TransformedItemContainer? toRemove = transformed.FirstOrDefault(t => ReferenceEquals(t.Source, change.Current));
var toRemove = transformed.FirstOrDefault(t => ReferenceEquals(t.Source, change.Current));

if (toRemove is not null)
{
Expand Down Expand Up @@ -188,15 +187,9 @@ public TransformedItemContainer(TSource source, TDestination destination)

public TSource Source { get; }

public static bool operator ==(TransformedItemContainer left, TransformedItemContainer right)
{
return Equals(left, right);
}
public static bool operator ==(TransformedItemContainer left, TransformedItemContainer right) => Equals(left, right);

public static bool operator !=(TransformedItemContainer left, TransformedItemContainer right)
{
return !Equals(left, right);
}
public static bool operator !=(TransformedItemContainer left, TransformedItemContainer right) => !Equals(left, right);

public bool Equals(TransformedItemContainer? other)
{
Expand Down Expand Up @@ -233,9 +226,6 @@ public override bool Equals(object? obj)
return Equals((TransformedItemContainer)obj);
}

public override int GetHashCode()
{
return Source is null ? 0 : EqualityComparer<TSource>.Default.GetHashCode(Source);
}
public override int GetHashCode() => Source is null ? 0 : EqualityComparer<TSource>.Default.GetHashCode(Source);
}
}

0 comments on commit ba8d3c8

Please sign in to comment.