https://github.com/emako/defer
Provides IDeferable to emulate Golang's defer keyword in C#.
https://github.com/emako/defer
Last synced: 5 months ago
JSON representation
Provides IDeferable to emulate Golang's defer keyword in C#.
- Host: GitHub
- URL: https://github.com/emako/defer
- Owner: emako
- License: mit
- Created: 2024-11-15T10:27:28.000Z (over 1 year ago)
- Default Branch: master
- Last Pushed: 2024-11-18T07:18:01.000Z (over 1 year ago)
- Last Synced: 2025-10-29T03:49:04.894Z (9 months ago)
- Language: C#
- Homepage:
- Size: 30.3 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Defer
This repository provides `IDeferable` to emulate Golang's `defer` keyword in C#.
## Installing
[](https://nuget.org/packages/Defer)
The package is available [on NuGet](https://www.nuget.org/packages/Defer). To install, run:
```bash
dotnet add package Defer
```
## Build Status
[](https://github.com/emako/Defer/actions/workflows/library.nuget.yml)
## Usage
1. Usage of `Deferable`
```c#
// Deferable.Defer
Console.WriteLine("Hello, World!");
using (Deferable.Defer(() => Console.WriteLine("Goodbye, World!")))
{
Console.WriteLine("Do something");
}
// output:
// Hello, World!
// Do something
// Goodbye, World!
```
2. Usage of `Deferable`
```c#
// Deferable
int status = -1;
Console.WriteLine("init status: " + status);
using (Deferable.Defer(value => status = value, initValue: 1, deferValue: 0))
{
Console.WriteLine("doing something status: " + status);
}
Console.WriteLine("after defer status: " + status);
// output:
// init status: -1
// doing something status: 1
// after defer status: 0
```
3. Usage of `BooleanDeferable`
```c#
// BooleanDeferable
bool flag = default;
Console.WriteLine("init flag: " + flag);
using (BooleanDeferable.Defer(value => flag = value))
{
Console.WriteLine("doing something flag: " + flag);
}
Console.WriteLine("after defer flag: " + flag);
// output:
// init flag: False
// doing something flag: True
// after defer flag: False
```
4. Usage of `RefDeferable`
```c#
// RefDeferable
// Only applicable for .NET Standard 2.1, .NET Core 3.0, or later versions
double value = -1d;
Console.WriteLine("init value: " + value);
using (RefDeferable.Defer(ref value, 0d, 1d))
{
Console.WriteLine("doing something value: " + value);
}
Console.WriteLine("after defer value: " + value);
// output:
// init value: -1
// doing something value: 0
// after defer value: 1
```
## Comparison
> Comparison with Go's `defer`
In Go, `defer` is a keyword used to ensure that a function call is performed later in a program's execution, usually for purposes of cleanup.
```go
fmt.Println("Hello, World!")
defer fmt.Println("Goodbye, World!")
fmt.Println("Do something")
```
In C#, using this library, you can achieve similar behavior with `Deferable.Defer` and the `using` statement.
```csharp
Console.WriteLine("Hello, World!");
using IDeferable defer = Deferable.Defer(() => Console.WriteLine("Goodbye, World!"));
Console.WriteLine("Do something");
```
Both snippets output:
```text
Hello, World!
Do something
Goodbye, World!
```
## Before / After
Previously you might show and hide a loading indicator with a try/finally block:
```csharp
// Before: try/finally
bool _isLoading = false;
try
{
_isLoading = true;
// Do work that shows loading indicator
}
finally
{
_isLoading = false;
}
```
With this library you can achieve the same with two lines using `Deferable`: the show and hide logic stay next to each other, the code is simpler and more readable.
```csharp
// After: Deferable
bool _isLoading = false;
_isLoading = true;
using IDeferable _ = Deferable.Defer(() => _isLoading = false);
// Do work while loading; when the scope exits, loading is hidden automatically
```
This keeps the show/hide logic colocated, reduces boilerplate, and improves readability.
## References
https://blog.coldwind.top/posts/mimic-go-defer-in-csharp/