RZ.Foundation
7.0.0
dotnet add package RZ.Foundation --version 7.0.0
NuGet\Install-Package RZ.Foundation -Version 7.0.0
<PackageReference Include="RZ.Foundation" Version="7.0.0" />
paket add RZ.Foundation --version 7.0.0
#r "nuget: RZ.Foundation, 7.0.0"
// Install RZ.Foundation as a Cake Addin #addin nuget:?package=RZ.Foundation&version=7.0.0 // Install RZ.Foundation as a Cake Tool #tool nuget:?package=RZ.Foundation&version=7.0.0
RZ Functional library for C#
This library is an add-on to LanguageExt library. It tries to provide some syntactic sugar for more natural expression.
Option[T] Extension (RZ.Foundation)
Convert between C# nullable value and Option[T]
Prelude module provides conversion functions for C# nullable and Option[T]. Unfortunately, Value Type/Ref Type semantic differences make creating generic functions to support both meta-types tedious and, in some case, confuse the compiler and generating a warning.
using static LanguageExt.Prelude;
int? x = 123;
Option<T> y = Some(x); // convert a nullable value to Option<T>
int? z = y.ToNullable(); // convert an Option<T> to a nullable value
// this should also work with nullable ref value
string? a = "Hello";
Option<string> b = Some(a);
string? c = b.ToNullable();
Getting a value out of Option[T]
Suppose that we have follow option values:
using static LanguageExt.Prelude;
var some = Some(123);
var none = Option<int>.None;
Get
var x = some.Get(); // 123
var y = none.Get(); // an exception is thrown!
GetOrThrow
In case you want to specific an exception.
var x = some.GetOrThrow(() => new MyException()); // 123
var y = none.GetOrThrow(() => new MyException()); // MyException is thrown!
GetOrDefault
var x = some.GetOrDefault(); // 123
var y = none.GetOrDefault(); // 0, int's default value
Replace None value
using static LanguageExt.Prelude;
var x = Option<int>.None;
var y = x.OrElse(123); // Option<int> of 123
var z = x.OrElse(Some(456)) // Option<int> of 456
var a = x.OrElse(() => None); // stay None
var b = await x.OrElseAsync(() => Task.FromResult(999)); // Option<int> of 999
Perform action (Side effect)
Then
is the operation to perform an action. The method returns the original value.
using static LanguageExt.Prelude;
var x = None<int>();
x.Then(v => Console.WriteLine("Value = {0}", v));
x.Then(v => Console.WriteLine("Value = {0}", v), () => Console.WriteLine("No value"));
// async versions
await x.ThenAsync(v => Task.Run(() => Console.WriteLine("V = {0}", v)));
await x.ThenAsync(v => Task.Run(() => Console.WriteLine("V = {0}", v)),
() => Task.Run(() => Console.WriteLine("No value")));
Type casting
Option<object> x = Some((object) "I am string");
Option<string> y = x.TryCast<object,string>();
Option<int> z = x.TryCast<object,int>(); // None!
TaskOption[T]
LanguageExt's OptionAsync
should be a wrapper of Task<Option<T>>
, but its recent async/await handler
has been implemented in way that consumes all exceptions as None
value. This makes sense when we don’t
want any side-effect. But in case of exception handling, I find that by allowing exceptions as the side-effect,
would simplify error handling code when writing in functional paradigm.
So TaskOption<T>
is made to work similar to OptionAsync
but with async/await pattern that allows
exceptions to be escalated normally, as well as, support None
returning value.
Nullable as Option like
int? x = 123;
string MyToString(int a) => a.ToString();
string? y = x.Apply(MyToString); // "123"
On(x)
Catch
var x = Task.FromResult(123);
var y = await On(x).Catch(_ => -1);
y.Should().Be(123);
BeforeThrow
var x = Task.FromException<int>(new Exception("Test"));
bool effect = false;
Func<Task> action = () => On(x).BeforeThrow(_ => effect = true);
await action.Should().ThrowAsync<Exception>();
effect.Should().BeTrue();
Utilities
ToReadOnlyCollection
Convert ICollection
to IReadOnlyCollection
with ToReadOnlyCollection()
.
Encryption
var nonce = Encryption.NonceFromASCII("Hello test");
var key = Encryption.CreateAesKey();
var aes = Encryption.CreateAes(key, nonce);
var encrypted = aes.Encrypt("Hello world");
var decrypted = aes.Decrypt(encrypted);
JSON deserialization of derived classes
Introduce a RzJsonDerivedType
attribute to support JSON deserialization of derived classes. This is an alternative
solution to .NET 7 JsonDerivedType
solution.
enum PersonType
{
[JsonStringEnumMemberName("student")] Student,
[JsonStringEnumMemberName("teacher")] Teacher
}
abstract record Person(PersonType Type);
[RzJsonDerivedType(PersonType.Student)]
sealed record Student(string Id) : Person(PersonType.Student);
[RzJsonDerivedType(PersonType.Teacher)]
sealed record Teacher(string Subject) : Person(PersonType.Teacher);
static readonly JsonSerializerOptions Options = new JsonSerializerOptions {
Converters = { new TypedClassConverter([typeof(Person).Assembly]) }
}.UseRzRecommendedSettings();
[Fact]
public void DeserializeStudent() {
var json = """{"type":"student","id":"42"}""";
var student = JsonSerializer.Deserialize<Person>(json, Options);
student.Should().BeOfType<Student>();
student.As<Student>().Id.Should().Be("42", $"but {student}");
}
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. |
-
net9.0
- JetBrains.Annotations (>= 2024.3.0)
- LanguageExt.Core (>= 4.4.9)
NuGet packages (6)
Showing the top 5 NuGet packages that depend on RZ.Foundation:
Package | Downloads |
---|---|
RZ.Foundation.NewtonsoftJson
RZ.Foundation extension for Newtonsoft.JSON |
|
RZ.Linq.RelationalDatabase
Transform LINQ to SQL text |
|
RZ.Foundation.Blazor
Package Description |
|
RZ.AspNet.Bootstrapper
Package Description |
|
RZ.Foundation.MongoDb
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
7.0.0 | 81 | 2/4/2025 |
7.0.0-beta.26 | 58 | 10/15/2024 |
7.0.0-beta.12 | 50 | 9/25/2024 |
7.0.0-beta.11 | 60 | 9/22/2024 |
7.0.0-beta.3 | 74 | 6/23/2024 |
7.0.0-alpha.3 | 72 | 6/22/2024 |
6.5.0-beta.1 | 68 | 5/9/2024 |
6.4.0 | 402 | 4/22/2024 |
6.3.1 | 411 | 11/27/2023 |
6.3.0 | 266 | 11/15/2023 |
6.2.0 | 278 | 11/12/2023 |
6.1.2 | 366 | 8/27/2023 |
6.1.1 | 424 | 7/6/2023 |
6.1.0 | 313 | 7/6/2023 |
6.0.1 | 299 | 6/18/2023 |
6.0.0 | 414 | 3/14/2023 |
5.1.0-beta.4 | 403 | 9/10/2022 |
5.0.10 | 701 | 8/20/2022 |
5.0.9 | 550 | 8/18/2022 |
5.0.8 | 1,254 | 6/23/2022 |
5.0.4 | 266 | 12/26/2021 |
5.0.1 | 460 | 12/18/2021 |
5.0.0 | 1,336 | 12/4/2020 |
3.1.0 | 981 | 10/25/2020 |
3.0.2 | 1,609 | 7/11/2020 |
3.0.1 | 615 | 7/11/2020 |
3.0.0 | 645 | 6/29/2020 |
2.0.5 | 599 | 6/12/2020 |
2.0.4 | 5,550 | 5/17/2020 |
2.0.3 | 960 | 3/18/2020 |
2.0.2 | 510 | 3/17/2020 |
2.0.0 | 544 | 3/16/2020 |
1.5.0 | 534 | 3/13/2020 |
1.4.4 | 616 | 3/3/2020 |
1.4.3 | 673 | 1/19/2020 |
1.4.1 | 541 | 1/18/2020 |
1.4.0 | 526 | 1/18/2020 |
1.3.8 | 597 | 12/8/2019 |
1.3.5 | 586 | 12/4/2019 |
1.3.2 | 713 | 10/7/2019 |
1.3.1 | 562 | 9/2/2019 |
1.2.9 | 581 | 8/14/2019 |
1.2.7 | 596 | 7/27/2019 |
1.2.5 | 589 | 7/25/2019 |
1.2.2 | 617 | 7/20/2019 |
1.2.1 | 546 | 7/20/2019 |
1.2.0 | 581 | 7/19/2019 |
1.1.1.1 | 633 | 4/28/2019 |
1.0.10 | 893 | 8/20/2018 |
1.0.9 | 1,027 | 2/19/2018 |
1.0.0 | 989 | 2/8/2018 |
Embrace LanguageExt lib.