MicroElements source only package: Collection extensions: NotNull, Iterate, Execute, WhereNotNull, Materialize, IncludeByWildcardPatterns, ExcludeByWildcardPatterns. Special collections: Cache, TwoLayerCache, PollingCache.
$ dotnet add package MicroElements.Collections.SourcesMicroElements source only package: Collection extensions: NotNull, Iterate, Execute, WhereNotNull, Materialize, IncludeByWildcardPatterns, ExcludeByWildcardPatterns. Special collections: TwoLayerCache.
Returns not null (empty) enumeration if input is null.
string? GetFirstValue(IEnumerable<string>? optionalValues) =>
optionalValues
.NotNull()
.FirstOrDefault();
Enumerates only not null values.
string?[] namesWithNulls = {"Alex", null, "John"};
string[] names = namesWithNulls.WhereNotNull().ToArray();
Iterates values and executes action for each value.
It's like List.ForEach but works with lazy enumerations and does not forces additional allocations.
// Iterates values and outputs to console.
Enumerable
.Range(1, 100_000)
.Iterate(Console.WriteLine);
Execute extension allows to execute an action on each value while enumerating the source enumeration.
This method is pure LINQ method, with postponed enumeration, also it can be chained.
Enumerable
.Range(1, 10)
.Execute(Console.WriteLine)
.Iterate();
Materializes source enumeration and allows to see intermediate results without changing execute chain. MaterializeDebug is the same as Materialize but works only in Debug mode and does not affect performance for Release builds.
Enumerable
.Range(1, 10)
.Materialize(values => { /*set breakpoint here*/ })
.Iterate(Console.WriteLine);
Provides methods for wildcard or glob filtering.
See also: https://en.wikipedia.org/wiki/Glob_(programming).
[Fact]
public void WildcardInclude()
{
string[] values = { "Microsoft.Extension.Logging", "Microsoft.AspNetCore.Hosting", "FluentAssertions", "System.Collections.Generic" };
string[] includePatterns = { "Microsoft.AspNetCore.*", "*.Collections.*" };
string[] result = { "Microsoft.AspNetCore.Hosting", "System.Collections.Generic" };
values.IncludeByWildcardPatterns(includePatterns).Should().BeEquivalentTo(result);
}
[Fact]
public void WildcardExclude()
{
string[] values = { "Microsoft.Extension.Logging", "Microsoft.AspNetCore.Hosting", "FluentAssertions", "System.Collections.Generic" };
string[] excludePatterns = { "Microsoft.AspNetCore.*", "*.Collections.*" };
string[] result = { "Microsoft.Extension.Logging", "FluentAssertions" };
values.ExcludeByWildcardPatterns(excludePatterns).Should().BeEquivalentTo(result);
}
Represents ThreadSafe cache that holds only limited number of items. Can be used as drop in replacement for ConcurrentDictionary.
Use it when you need simple cache but with memory limit.
Notes:
Global ambient cache extensions.
Represents ConcurrentDictionary of some type that is accessed by it's name.
Reason: Use cache from any place of your code without declaring cache (that's so boring and noisy). Best suited for global caches of immutable objects that never changes in application lifecycle.
// Static named cache
var value = Cache
.Instance<string, string>("Example")
.GetOrAdd("key1", k => VeryLongFetch(k));// Cache attached to instance
var value = instance
.GetWeakCache<string, string>(/*optional name*/)
.GetOrAdd("key1", k => VeryLongFetch(k));TwoLayerCache