Skip to content

Commit ba8d3c8

Browse files
Fix shared state issue in List.Transform. Fixes #618 (#619)
1 parent fcb0217 commit ba8d3c8

4 files changed

Lines changed: 25 additions & 24 deletions

File tree

src/DynamicData.Tests/List/TransformFixture.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,22 @@ public void Update()
144144
_results.Messages[0].Adds.Should().Be(1, "Should be 1 adds");
145145
_results.Messages[0].Replaced.Should().Be(0, "Should be 1 update");
146146
}
147+
148+
149+
[Fact]
150+
public void MultipleSubscribersShouldNotShareState()
151+
{
152+
_source.AddRange(new Person[]
153+
{
154+
new ("Adult1", 50),
155+
new ("Adult2", 51)
156+
});
157+
158+
var transformed = _source.Connect()
159+
.Transform(o => o);
160+
161+
// will throw if state of ChangeAwareList is shared
162+
transformed.Transform(o => o).Subscribe();
163+
transformed.Transform(o => o).Subscribe();
164+
}
147165
}

src/DynamicData/List/Internal/TransformAsync.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,8 @@
22
// Roland Pheasant licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for full license information.
44

5-
using System;
6-
using System.Collections.Generic;
7-
using System.Linq;
85
using System.Reactive.Linq;
96
using System.Reactive.Threading.Tasks;
10-
using System.Threading.Tasks;
117

128
namespace DynamicData.List.Internal;
139

src/DynamicData/List/Internal/TransformMany.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,8 @@
22
// Roland Pheasant licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for full license information.
44

5-
using System;
65
using System.Collections;
7-
using System.Collections.Generic;
86
using System.Collections.ObjectModel;
9-
using System.Linq;
107
using System.Reactive.Disposables;
118
using System.Reactive.Linq;
129

src/DynamicData/List/Internal/Transformer.cs

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ public Transformer(IObservable<IChangeSet<TSource>> source, Func<TSource, Option
3131
_containerFactory = (item, prev, index) => new TransformedItemContainer(item, factory(item, prev, index));
3232
}
3333

34-
public IObservable<IChangeSet<TDestination>> Run()
35-
{
36-
return _source.Scan(new ChangeAwareList<TransformedItemContainer>(), (state, changes) =>
34+
public IObservable<IChangeSet<TDestination>> Run() => Observable.Defer(RunImpl);
35+
36+
private IObservable<IChangeSet<TDestination>> RunImpl() => _source.Scan(new ChangeAwareList<TransformedItemContainer>(), (state, changes) =>
3737
{
3838
Transform(state, changes);
3939
return state;
@@ -43,7 +43,6 @@ public IObservable<IChangeSet<TDestination>> Run()
4343
var changed = transformed.CaptureChanges();
4444
return changed.Transform(container => container.Destination);
4545
});
46-
}
4746

4847
private void Transform(ChangeAwareList<TransformedItemContainer> transformed, IChangeSet<TSource> changes)
4948
{
@@ -125,7 +124,7 @@ private void Transform(ChangeAwareList<TransformedItemContainer> transformed, IC
125124
}
126125
else
127126
{
128-
TransformedItemContainer? toRemove = transformed.FirstOrDefault(t => ReferenceEquals(t.Source, change.Current));
127+
var toRemove = transformed.FirstOrDefault(t => ReferenceEquals(t.Source, change.Current));
129128

130129
if (toRemove is not null)
131130
{
@@ -188,15 +187,9 @@ public TransformedItemContainer(TSource source, TDestination destination)
188187

189188
public TSource Source { get; }
190189

191-
public static bool operator ==(TransformedItemContainer left, TransformedItemContainer right)
192-
{
193-
return Equals(left, right);
194-
}
190+
public static bool operator ==(TransformedItemContainer left, TransformedItemContainer right) => Equals(left, right);
195191

196-
public static bool operator !=(TransformedItemContainer left, TransformedItemContainer right)
197-
{
198-
return !Equals(left, right);
199-
}
192+
public static bool operator !=(TransformedItemContainer left, TransformedItemContainer right) => !Equals(left, right);
200193

201194
public bool Equals(TransformedItemContainer? other)
202195
{
@@ -233,9 +226,6 @@ public override bool Equals(object? obj)
233226
return Equals((TransformedItemContainer)obj);
234227
}
235228

236-
public override int GetHashCode()
237-
{
238-
return Source is null ? 0 : EqualityComparer<TSource>.Default.GetHashCode(Source);
239-
}
229+
public override int GetHashCode() => Source is null ? 0 : EqualityComparer<TSource>.Default.GetHashCode(Source);
240230
}
241231
}

0 commit comments

Comments
 (0)