SG.NullableExtensions
1.0.0
dotnet add package SG.NullableExtensions --version 1.0.0
NuGet\Install-Package SG.NullableExtensions -Version 1.0.0
<PackageReference Include="SG.NullableExtensions" Version="1.0.0" />
paket add SG.NullableExtensions --version 1.0.0
#r "nuget: SG.NullableExtensions, 1.0.0"
// Install SG.NullableExtensions as a Cake Addin #addin nuget:?package=SG.NullableExtensions&version=1.0.0 // Install SG.NullableExtensions as a Cake Tool #tool nuget:?package=SG.NullableExtensions&version=1.0.0
Nullable Extensions
This is a set of extension methods for C# nullable types (reference types and the Nullable<T> struct) that allow you to ger rid of if statements used to check for null.
Methods
All of these methods has async overloads.
You can find them in SG.NullableExtensions.Tasks
and SG.NullableExtensions.ValueTasks
namespaces.
Inspect
Inspect()
performs an action against a value if the value is not null.
var product = products.FirstOrDefault(p => p.Code == Code);
product.Inspect(product => product.UpdatedDate = DateTime.NowUtc);
Inspect()
has async overloads that support both Task<T>
and ValueTask<T>
:
var delivery = await delivery.GetProductAsync(id);
await product.InspectAsync(p => {
p.Address = await addressService.GetByPostalCodeAsync(p.PostalCode)
});
In addition to that, there are extensions for ValueTask<T?>
and Task<T?>
,
they will await the given tasks for you if needed, so the Inspect()
is applied to the output of the task.
await serializer.SerializeAsync()
.InspectAsync(message => processor.ProcessAsync(message)); // takes Task<T?>, applies Func<T, Task>
WhenNull
This method as opposed to Inspect()
calls the delegate when the value is null.
await serializer.Serialize()
.WhenNull(message => logger.LogError("Failed to serialize a message!"));
Please, note: Inspect()
and WhenNull()
return the unchanged value, so you can combine these methods:
await serializer.Serialize()
.WhenNull(() => logger.LogError("Failed to serialize message!"))
.Inspect(message => logger.LogInformation(message))
.Inspect(message => processor.Process(message));
WhenNull()
has the same set of async overloads as Inspect()
.
await serializer.SerializeAsync()
.WhenNullAsync(() => logger.NotifyAsync("Failed to serialize a message!")); // takes Task<T?>, applies Func<Task>
});
await serializer.Serialize()
.WhenNullAsync(() => notifier.NotifyAsync("Failed to serialize message!")); // takes T?, applies Func<Task>
Is
Checks if the underlying value is not null. If so, it'll run specified predicate.
var user = userService.GetUser(id);
user.Is(u => u.EmailAddress == emailAddress);
Also, async overloads available.
var user = userService.GetUser(id);
await user.IsAsync(u => userOrderService.HasPendingOrdersAsync(u.Id));
await userService.GetUserAsync(id).IsAsync(u => userOrderService.HasPendingOrdersAsync(u.Id));
Map
Transforms the underlying value if it is not null.
var user = await dbContext.User
.FirstOrDefault(u => u.Id == id)
.Map(u => new UserModel(u));
Supports an async overload:
var user = await httpContext.Read()
.MapAsync(b => JsonSerializer.DeserializeAsync<User>(u));
ValueTask<T?>
and Task<T?>
overloads are supported as well:
var authorizationResult = await httpContext.ReadAsJsonAsync<Credentials>()
.MapAsync(credentials => authService.AuthorizeAsync(credentials));
var userDto = await httpContext.ReadAsJsonAsync<User>()
.MapAsync(credentials => mapper.Map<UserDto>());
ValueOr
Tries to unwrap the underlying value. If the value is null, it will return specified default value.
var address = employee.Address.ValueOr(new Address());
Also, there is an overload that uses a factory instead of a plain value.
var address = employee.Address.ValueOr(() => addressService.GetDefaultAddress());
There are also async overloads including ValueTas<T>
and Task<T>
extensions.
var apiKey = await apiKeysCache
.Get()
.ValueOrAsync(() => await apiKeysService.RefreshAsync())
.InspectAsync(key => await apiKeysCache.SetAsync(key))
var apiKey = await apiKeysCache
.GetAsync()
.ValueOrAsync(() => await apiKeysService.RefreshAsync()) // takes Task<T?>, applies Func<Task>
.InspectAsync(key => await apiKeysCache.SetAsync(key))
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net8.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.