From dfed59c04dafb598db5c0df0fc284346948327eb Mon Sep 17 00:00:00 2001 From: Alex Peck Date: Sun, 24 Jul 2022 12:53:18 -0700 Subject: [PATCH 1/6] icache+asynccache --- BitFaster.Caching/IAsyncCache.cs | 2 +- BitFaster.Caching/ICache.cs | 2 +- BitFaster.Caching/IScopedCache.cs | 2 +- .../Synchronized/AtomicFactoryAsyncCache.cs | 14 ++++++++++++++ .../Synchronized/AtomicFactoryCache.cs | 14 ++++++++++++++ 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/BitFaster.Caching/IAsyncCache.cs b/BitFaster.Caching/IAsyncCache.cs index 7f837876..5710d866 100644 --- a/BitFaster.Caching/IAsyncCache.cs +++ b/BitFaster.Caching/IAsyncCache.cs @@ -11,7 +11,7 @@ namespace BitFaster.Caching /// /// The type of keys in the cache. /// The type of values in the cache. - public interface IAsyncCache + public interface IAsyncCache : IEnumerable> { /// /// Gets the total number of items that can be stored in the cache. diff --git a/BitFaster.Caching/ICache.cs b/BitFaster.Caching/ICache.cs index dbb9e892..82dd44db 100644 --- a/BitFaster.Caching/ICache.cs +++ b/BitFaster.Caching/ICache.cs @@ -11,7 +11,7 @@ namespace BitFaster.Caching /// /// The type of keys in the cache. /// The type of values in the cache. - public interface ICache + public interface ICache : IEnumerable> { /// /// Gets the total number of items that can be stored in the cache. diff --git a/BitFaster.Caching/IScopedCache.cs b/BitFaster.Caching/IScopedCache.cs index e06f11c1..af0bc196 100644 --- a/BitFaster.Caching/IScopedCache.cs +++ b/BitFaster.Caching/IScopedCache.cs @@ -11,7 +11,7 @@ namespace BitFaster.Caching /// /// The type of keys in the cache. /// The type of values in the cache. - public interface IScopedCache where V : IDisposable + public interface IScopedCache where V : IDisposable { /// /// Gets the total number of items that can be stored in the cache. diff --git a/BitFaster.Caching/Synchronized/AtomicFactoryAsyncCache.cs b/BitFaster.Caching/Synchronized/AtomicFactoryAsyncCache.cs index 467d7f6b..3d38eaba 100644 --- a/BitFaster.Caching/Synchronized/AtomicFactoryAsyncCache.cs +++ b/BitFaster.Caching/Synchronized/AtomicFactoryAsyncCache.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; @@ -76,6 +77,19 @@ public bool TryUpdate(K key, V value) return cache.TryUpdate(key, new AsyncAtomicFactory(value)); } + public IEnumerator> GetEnumerator() + { + foreach (var kvp in this.cache) + { + yield return new KeyValuePair(kvp.Key, kvp.Value.ValueIfCreated); + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((AtomicFactoryAsyncCache)this).GetEnumerator(); + } + private class EventProxy : CacheEventProxyBase, V> { public EventProxy(ICacheEvents> inner) diff --git a/BitFaster.Caching/Synchronized/AtomicFactoryCache.cs b/BitFaster.Caching/Synchronized/AtomicFactoryCache.cs index e84a74c3..3b9a4145 100644 --- a/BitFaster.Caching/Synchronized/AtomicFactoryCache.cs +++ b/BitFaster.Caching/Synchronized/AtomicFactoryCache.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; @@ -76,6 +77,19 @@ public bool TryUpdate(K key, V value) return cache.TryUpdate(key, new AtomicFactory(value)); } + public IEnumerator> GetEnumerator() + { + foreach (var kvp in this.cache) + { + yield return new KeyValuePair(kvp.Key, kvp.Value.ValueIfCreated); + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((AtomicFactoryCache)this).GetEnumerator(); + } + private class EventProxy : CacheEventProxyBase, V> { public EventProxy(ICacheEvents> inner) From 4c29e787e9ba87ecbea128e25db783cb0537d61d Mon Sep 17 00:00:00 2001 From: Alex Peck Date: Sun, 24 Jul 2022 12:59:14 -0700 Subject: [PATCH 2/6] keys --- BitFaster.Caching/IAsyncCache.cs | 5 +++++ BitFaster.Caching/ICache.cs | 5 +++++ BitFaster.Caching/Synchronized/AtomicFactoryAsyncCache.cs | 2 ++ BitFaster.Caching/Synchronized/AtomicFactoryCache.cs | 2 ++ 4 files changed, 14 insertions(+) diff --git a/BitFaster.Caching/IAsyncCache.cs b/BitFaster.Caching/IAsyncCache.cs index 5710d866..a5d46ecc 100644 --- a/BitFaster.Caching/IAsyncCache.cs +++ b/BitFaster.Caching/IAsyncCache.cs @@ -33,6 +33,11 @@ public interface IAsyncCache : IEnumerable> /// ICacheEvents Events { get; } + /// + /// Gets a collection containing the keys in the cache. + /// + ICollection Keys { get; } + /// /// Attempts to get the value associated with the specified key from the cache. /// diff --git a/BitFaster.Caching/ICache.cs b/BitFaster.Caching/ICache.cs index 82dd44db..5ecb804e 100644 --- a/BitFaster.Caching/ICache.cs +++ b/BitFaster.Caching/ICache.cs @@ -33,6 +33,11 @@ public interface ICache : IEnumerable> /// ICacheEvents Events { get; } + /// + /// Gets a collection containing the keys in the cache. + /// + ICollection Keys { get; } + /// /// Attempts to get the value associated with the specified key from the cache. /// diff --git a/BitFaster.Caching/Synchronized/AtomicFactoryAsyncCache.cs b/BitFaster.Caching/Synchronized/AtomicFactoryAsyncCache.cs index 3d38eaba..1c8d0cd3 100644 --- a/BitFaster.Caching/Synchronized/AtomicFactoryAsyncCache.cs +++ b/BitFaster.Caching/Synchronized/AtomicFactoryAsyncCache.cs @@ -31,6 +31,8 @@ public AtomicFactoryAsyncCache(ICache> cache) public ICacheEvents Events => this.eventProxy; + public ICollection Keys => this.cache.Keys; + public void AddOrUpdate(K key, V value) { cache.AddOrUpdate(key, new AsyncAtomicFactory(value)); diff --git a/BitFaster.Caching/Synchronized/AtomicFactoryCache.cs b/BitFaster.Caching/Synchronized/AtomicFactoryCache.cs index 3b9a4145..1883dd6b 100644 --- a/BitFaster.Caching/Synchronized/AtomicFactoryCache.cs +++ b/BitFaster.Caching/Synchronized/AtomicFactoryCache.cs @@ -31,6 +31,8 @@ public AtomicFactoryCache(ICache> cache) public ICacheEvents Events => this.eventProxy; + public ICollection Keys => this.cache.Keys; + public void AddOrUpdate(K key, V value) { this.cache.AddOrUpdate(key, new AtomicFactory(value)); From ac68535b4c56c20e31c7aa9360d99f84d59f3536 Mon Sep 17 00:00:00 2001 From: Alex Peck Date: Sun, 24 Jul 2022 14:18:22 -0700 Subject: [PATCH 3/6] tests --- .../AtomicFactoryAsyncCacheTests.cs | 30 +++++++++++++++++++ .../Synchronized/AtomicFactoryCacheTests.cs | 30 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/BitFaster.Caching.UnitTests/Synchronized/AtomicFactoryAsyncCacheTests.cs b/BitFaster.Caching.UnitTests/Synchronized/AtomicFactoryAsyncCacheTests.cs index c4793d1b..152b19d4 100644 --- a/BitFaster.Caching.UnitTests/Synchronized/AtomicFactoryAsyncCacheTests.cs +++ b/BitFaster.Caching.UnitTests/Synchronized/AtomicFactoryAsyncCacheTests.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; @@ -147,6 +148,35 @@ public void WhenKeyExistsTryUpdateReturnsTrue() value.Should().Be(2); } + [Fact] + public void WhenItemsAddedKeysContainsTheKeys() + { + cache.Count.Should().Be(0); + cache.AddOrUpdate(1, 1); + cache.AddOrUpdate(2, 2); + cache.Keys.Should().BeEquivalentTo(new[] { 1, 2 }); + } + + [Fact] + public void WhenItemsAddedGenericEnumerateContainsKvps() + { + cache.Count.Should().Be(0); + cache.AddOrUpdate(1, 1); + cache.AddOrUpdate(2, 2); + cache.Should().BeEquivalentTo(new[] { new KeyValuePair(1, 1), new KeyValuePair(2, 2) }); + } + + [Fact] + public void WhenItemsAddedEnumerateContainsKvps() + { + cache.Count.Should().Be(0); + cache.AddOrUpdate(1, 1); + cache.AddOrUpdate(2, 2); + + var enumerable = (IEnumerable)cache; + enumerable.Should().BeEquivalentTo(new[] { new KeyValuePair(1, 1), new KeyValuePair(2, 2) }); + } + private void OnItemRemoved(object sender, ItemRemovedEventArgs e) { this.removedItems.Add(e); diff --git a/BitFaster.Caching.UnitTests/Synchronized/AtomicFactoryCacheTests.cs b/BitFaster.Caching.UnitTests/Synchronized/AtomicFactoryCacheTests.cs index 722882d1..10dc7611 100644 --- a/BitFaster.Caching.UnitTests/Synchronized/AtomicFactoryCacheTests.cs +++ b/BitFaster.Caching.UnitTests/Synchronized/AtomicFactoryCacheTests.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; @@ -147,6 +148,35 @@ public void WhenKeyExistsTryUpdateReturnsTrue() value.Should().Be(2); } + [Fact] + public void WhenItemsAddedKeysContainsTheKeys() + { + cache.Count.Should().Be(0); + cache.AddOrUpdate(1, 1); + cache.AddOrUpdate(2, 2); + cache.Keys.Should().BeEquivalentTo(new[] { 1, 2 }); + } + + [Fact] + public void WhenItemsAddedGenericEnumerateContainsKvps() + { + cache.Count.Should().Be(0); + cache.AddOrUpdate(1, 1); + cache.AddOrUpdate(2, 2); + cache.Should().BeEquivalentTo(new[] { new KeyValuePair(1, 1), new KeyValuePair(2, 2) }); + } + + [Fact] + public void WhenItemsAddedEnumerateContainsKvps() + { + cache.Count.Should().Be(0); + cache.AddOrUpdate(1, 1); + cache.AddOrUpdate(2, 2); + + var enumerable = (IEnumerable)cache; + enumerable.Should().BeEquivalentTo(new[] { new KeyValuePair(1, 1), new KeyValuePair(2, 2) }); + } + private void OnItemRemoved(object sender, ItemRemovedEventArgs e) { this.removedItems.Add(e); From 574af121686a2ea31733c7de6ae2b443f298c361 Mon Sep 17 00:00:00 2001 From: Alex Peck Date: Sun, 24 Jul 2022 14:34:30 -0700 Subject: [PATCH 4/6] enumerate scoped --- BitFaster.Caching/IScopedAsyncCache.cs | 7 ++++++- BitFaster.Caching/IScopedCache.cs | 7 ++++++- BitFaster.Caching/ScopedAsyncCache.cs | 17 +++++++++++++++++ BitFaster.Caching/ScopedCache.cs | 17 +++++++++++++++++ .../AtomicFactoryScopedAsyncCache.cs | 17 +++++++++++++++++ .../Synchronized/AtomicFactoryScopedCache.cs | 17 +++++++++++++++++ 6 files changed, 80 insertions(+), 2 deletions(-) diff --git a/BitFaster.Caching/IScopedAsyncCache.cs b/BitFaster.Caching/IScopedAsyncCache.cs index 32ba7150..ae5e08cd 100644 --- a/BitFaster.Caching/IScopedAsyncCache.cs +++ b/BitFaster.Caching/IScopedAsyncCache.cs @@ -11,7 +11,7 @@ namespace BitFaster.Caching /// /// The type of keys in the cache. /// The type of values in the cache. - public interface IScopedAsyncCache where V : IDisposable + public interface IScopedAsyncCache : IEnumerable>> where V : IDisposable { /// /// Gets the total number of items that can be stored in the cache. @@ -37,6 +37,11 @@ public interface IScopedAsyncCache where V : IDisposable /// ICacheEvents> Events { get; } + /// + /// Gets a collection containing the keys in the cache. + /// + ICollection Keys { get; } + /// /// Attempts to create a lifetime for the value associated with the specified key from the cache /// diff --git a/BitFaster.Caching/IScopedCache.cs b/BitFaster.Caching/IScopedCache.cs index af0bc196..7c3687d0 100644 --- a/BitFaster.Caching/IScopedCache.cs +++ b/BitFaster.Caching/IScopedCache.cs @@ -11,7 +11,7 @@ namespace BitFaster.Caching /// /// The type of keys in the cache. /// The type of values in the cache. - public interface IScopedCache where V : IDisposable + public interface IScopedCache : IEnumerable>> where V : IDisposable { /// /// Gets the total number of items that can be stored in the cache. @@ -37,6 +37,11 @@ public interface IScopedCache where V : IDisposable /// ICacheEvents> Events { get; } + /// + /// Gets a collection containing the keys in the cache. + /// + ICollection Keys { get; } + /// /// Attempts to create a lifetime for the value associated with the specified key from the cache /// diff --git a/BitFaster.Caching/ScopedAsyncCache.cs b/BitFaster.Caching/ScopedAsyncCache.cs index f15dbe53..1fd00183 100644 --- a/BitFaster.Caching/ScopedAsyncCache.cs +++ b/BitFaster.Caching/ScopedAsyncCache.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; @@ -40,6 +41,9 @@ public ScopedAsyncCache(IAsyncCache> cache) /// public ICacheEvents> Events => this.cache.Events; + /// + public ICollection Keys => this.cache.Keys; + /// public void AddOrUpdate(K key, V value) { @@ -107,5 +111,18 @@ public bool TryUpdate(K key, V value) { return this.cache.TryUpdate(key, new Scoped(value)); } + + public IEnumerator>> GetEnumerator() + { + foreach (var kvp in this.cache) + { + yield return kvp; + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((ScopedAsyncCache)this).GetEnumerator(); + } } } diff --git a/BitFaster.Caching/ScopedCache.cs b/BitFaster.Caching/ScopedCache.cs index 8d34e229..2c8476c0 100644 --- a/BitFaster.Caching/ScopedCache.cs +++ b/BitFaster.Caching/ScopedCache.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; @@ -40,6 +41,9 @@ public ScopedCache(ICache> cache) /// public ICacheEvents> Events => this.cache.Events; + /// + public ICollection Keys => this.cache.Keys; + /// public void AddOrUpdate(K key, V value) { @@ -107,5 +111,18 @@ public bool TryUpdate(K key, V value) { return this.cache.TryUpdate(key, new Scoped(value)); } + + public IEnumerator>> GetEnumerator() + { + foreach (var kvp in this.cache) + { + yield return kvp; + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((ScopedCache)this).GetEnumerator(); + } } } diff --git a/BitFaster.Caching/Synchronized/AtomicFactoryScopedAsyncCache.cs b/BitFaster.Caching/Synchronized/AtomicFactoryScopedAsyncCache.cs index 9ce1ecc8..ffc802ce 100644 --- a/BitFaster.Caching/Synchronized/AtomicFactoryScopedAsyncCache.cs +++ b/BitFaster.Caching/Synchronized/AtomicFactoryScopedAsyncCache.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; @@ -31,6 +32,9 @@ public AtomicFactoryScopedAsyncCache(ICache> c public ICacheEvents> Events => this.eventProxy; + /// + public ICollection Keys => this.cache.Keys; + public void AddOrUpdate(K key, V value) { this.cache.AddOrUpdate(key, new ScopedAsyncAtomicFactory(value)); @@ -94,6 +98,19 @@ public bool TryUpdate(K key, V value) return this.cache.TryUpdate(key, new ScopedAsyncAtomicFactory(value)); } + public IEnumerator>> GetEnumerator() + { + foreach (var kvp in this.cache) + { + yield return new KeyValuePair>(kvp.Key, kvp.Value.ScopeIfCreated); + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((AtomicFactoryScopedAsyncCache)this).GetEnumerator(); + } + private class EventProxy : CacheEventProxyBase, Scoped> { public EventProxy(ICacheEvents> inner) diff --git a/BitFaster.Caching/Synchronized/AtomicFactoryScopedCache.cs b/BitFaster.Caching/Synchronized/AtomicFactoryScopedCache.cs index 746d7670..309cf56f 100644 --- a/BitFaster.Caching/Synchronized/AtomicFactoryScopedCache.cs +++ b/BitFaster.Caching/Synchronized/AtomicFactoryScopedCache.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; @@ -31,6 +32,9 @@ public AtomicFactoryScopedCache(ICache> cache) public ICacheEvents> Events => this.eventProxy; + /// + public ICollection Keys => this.cache.Keys; + public void AddOrUpdate(K key, V value) { this.cache.AddOrUpdate(key, new ScopedAtomicFactory(value)); @@ -92,6 +96,19 @@ public bool TryUpdate(K key, V value) return this.cache.TryUpdate(key, new ScopedAtomicFactory(value)); } + public IEnumerator>> GetEnumerator() + { + foreach (var kvp in this.cache) + { + yield return new KeyValuePair>(kvp.Key, kvp.Value.ScopeIfCreated); + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((AtomicFactoryScopedCache)this).GetEnumerator(); + } + private class EventProxy : CacheEventProxyBase, Scoped> { public EventProxy(ICacheEvents> inner) From cbeeada69c657070e3369107131b5e2222ea2863 Mon Sep 17 00:00:00 2001 From: Alex Peck Date: Sun, 24 Jul 2022 14:51:15 -0700 Subject: [PATCH 5/6] test scoped --- .../ScopedAsyncCacheTestBase.cs | 41 +++++++++++++++++++ .../ScopedCacheTestBase.cs | 41 +++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/BitFaster.Caching.UnitTests/ScopedAsyncCacheTestBase.cs b/BitFaster.Caching.UnitTests/ScopedAsyncCacheTestBase.cs index be7cdd7b..c6802604 100644 --- a/BitFaster.Caching.UnitTests/ScopedAsyncCacheTestBase.cs +++ b/BitFaster.Caching.UnitTests/ScopedAsyncCacheTestBase.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; @@ -169,6 +170,46 @@ public void WhenKeyExistsTryUpdateReturnsTrue() this.cache.TryUpdate(1, new Disposable()).Should().BeTrue(); } + [Fact] + public void WhenItemsAddedKeysContainsTheKeys() + { + cache.Count.Should().Be(0); + cache.AddOrUpdate(1, new Disposable()); + cache.AddOrUpdate(2, new Disposable()); + cache.Keys.Should().BeEquivalentTo(new[] { 1, 2 }); + } + + [Fact] + public void WhenItemsAddedGenericEnumerateContainsKvps() + { + var d1 = new Disposable(); + var d2 = new Disposable(); + + cache.Count.Should().Be(0); + cache.AddOrUpdate(1, d1); + cache.AddOrUpdate(2, d2); + cache + .Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.CreateLifetime().Value)) + .Should().BeEquivalentTo(new[] { new KeyValuePair(1, d1), new KeyValuePair(2, d2) }); + } + + [Fact] + public void WhenItemsAddedEnumerateContainsKvps() + { + var d1 = new Disposable(); + var d2 = new Disposable(); + + cache.Count.Should().Be(0); + cache.AddOrUpdate(1, d1); + cache.AddOrUpdate(2, d2); + + var enumerable = (IEnumerable)cache; + enumerable + .Cast>>() + .Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.CreateLifetime().Value)) + .Should().BeEquivalentTo(new[] { new KeyValuePair(1, d1), new KeyValuePair(2, d2) }); + } + protected void OnItemRemoved(object sender, ItemRemovedEventArgs> e) { this.removedItems.Add(e); diff --git a/BitFaster.Caching.UnitTests/ScopedCacheTestBase.cs b/BitFaster.Caching.UnitTests/ScopedCacheTestBase.cs index 539fa390..0a46d76c 100644 --- a/BitFaster.Caching.UnitTests/ScopedCacheTestBase.cs +++ b/BitFaster.Caching.UnitTests/ScopedCacheTestBase.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; @@ -169,6 +170,46 @@ public void WhenKeyExistsTryUpdateReturnsTrue() this.cache.TryUpdate(1, new Disposable()).Should().BeTrue(); } + [Fact] + public void WhenItemsAddedKeysContainsTheKeys() + { + cache.Count.Should().Be(0); + cache.AddOrUpdate(1, new Disposable()); + cache.AddOrUpdate(2, new Disposable()); + cache.Keys.Should().BeEquivalentTo(new[] { 1, 2 }); + } + + [Fact] + public void WhenItemsAddedGenericEnumerateContainsKvps() + { + var d1 = new Disposable(); + var d2 = new Disposable(); + + cache.Count.Should().Be(0); + cache.AddOrUpdate(1, d1); + cache.AddOrUpdate(2, d2); + cache + .Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.CreateLifetime().Value)) + .Should().BeEquivalentTo(new[] { new KeyValuePair(1, d1), new KeyValuePair(2, d2) }); + } + + [Fact] + public void WhenItemsAddedEnumerateContainsKvps() + { + var d1 = new Disposable(); + var d2 = new Disposable(); + + cache.Count.Should().Be(0); + cache.AddOrUpdate(1, d1); + cache.AddOrUpdate(2, d2); + + var enumerable = (IEnumerable)cache; + enumerable + .Cast>>() + .Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.CreateLifetime().Value)) + .Should().BeEquivalentTo(new[] { new KeyValuePair(1, d1), new KeyValuePair(2, d2) }); + } + protected void OnItemRemoved(object sender, ItemRemovedEventArgs> e) { this.removedItems.Add(e); From f9b54b4cf205ed29d089fc0c0b911ac284a6f9f2 Mon Sep 17 00:00:00 2001 From: Alex Peck Date: Sun, 24 Jul 2022 15:00:59 -0700 Subject: [PATCH 6/6] test IEnumerable --- .../ScopedAsyncCacheTestBase.cs | 14 ++++++++++---- BitFaster.Caching.UnitTests/ScopedCacheTestBase.cs | 14 ++++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/BitFaster.Caching.UnitTests/ScopedAsyncCacheTestBase.cs b/BitFaster.Caching.UnitTests/ScopedAsyncCacheTestBase.cs index c6802604..02cbd16a 100644 --- a/BitFaster.Caching.UnitTests/ScopedAsyncCacheTestBase.cs +++ b/BitFaster.Caching.UnitTests/ScopedAsyncCacheTestBase.cs @@ -204,10 +204,16 @@ public void WhenItemsAddedEnumerateContainsKvps() cache.AddOrUpdate(2, d2); var enumerable = (IEnumerable)cache; - enumerable - .Cast>>() - .Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.CreateLifetime().Value)) - .Should().BeEquivalentTo(new[] { new KeyValuePair(1, d1), new KeyValuePair(2, d2) }); + + var list = new List>(); + + foreach (var i in enumerable) + { + var kvp = (KeyValuePair>)i; + list.Add(new KeyValuePair(kvp.Key, kvp.Value.CreateLifetime().Value)); + } + + list.Should().BeEquivalentTo(new[] { new KeyValuePair(1, d1), new KeyValuePair(2, d2) }); } protected void OnItemRemoved(object sender, ItemRemovedEventArgs> e) diff --git a/BitFaster.Caching.UnitTests/ScopedCacheTestBase.cs b/BitFaster.Caching.UnitTests/ScopedCacheTestBase.cs index 0a46d76c..1ac22135 100644 --- a/BitFaster.Caching.UnitTests/ScopedCacheTestBase.cs +++ b/BitFaster.Caching.UnitTests/ScopedCacheTestBase.cs @@ -204,10 +204,16 @@ public void WhenItemsAddedEnumerateContainsKvps() cache.AddOrUpdate(2, d2); var enumerable = (IEnumerable)cache; - enumerable - .Cast>>() - .Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.CreateLifetime().Value)) - .Should().BeEquivalentTo(new[] { new KeyValuePair(1, d1), new KeyValuePair(2, d2) }); + + var list = new List>(); + + foreach (var i in enumerable) + { + var kvp = (KeyValuePair>)i; + list.Add(new KeyValuePair(kvp.Key, kvp.Value.CreateLifetime().Value)); + } + + list.Should().BeEquivalentTo(new[] { new KeyValuePair(1, d1), new KeyValuePair(2, d2) }); } protected void OnItemRemoved(object sender, ItemRemovedEventArgs> e)