Uncategorized

Misusing C# 8 `using` to get Golang `defer` in DotNet Core 3

I started out with C# since then I’ve learned other languages and one of my favorites is Golang.

When I was reading the release notes from C# 8 I saw the new using declaration and through it was awesome… I also realized it could be misused to give C# the defer keyword from Golang.

Whats defer in Golang do?

defer in Golang lets you define a function that will get run when the code block exits.

The example below will print:

hello
world

Code: Try it out here


package main

import "fmt"

func main() {
    defer fmt.Println("world")
    fmt.Println("hello")
}

I’m a big fan of this approach as I think it’s clearer to read than the standard try finally pattern as it lets you put the cleanup code directly below the code which is making the mess like:

    f := createTempFile("/tmp/defer.txt")defer deleteTempFile(f)writeFile(f)        // here the `deleteTempFile` method gets called

How can we do this in C# 8 with the new using syntax?

Well now because using var x = new thing()exists you can write a simple class called defer which runs a function when the current method exits, just like in golang

The interesting thing is that as a using statement generates a try finally under the covers these defer functions will still run if an exception is thrown.

The example below will print:

Hello World!
Defer 2
Defer 1
Exception thrown: It's all one wrong

Code:

using System;
namespace deferdotnet
{
class Program
{
static void Main(string[] args)
{
try
{
DoStuff();
}
catch (Exception e)
{
Console.WriteLine($"Exception thrown: {e.Message}");
}
}
private static void DoStuff()
{
using var d = new Defer(() => Console.WriteLine("Defer 1"));
using var f = new Defer(() => Console.WriteLine("Defer 2"));
Console.WriteLine("Hello World!");
throw new Exception("It's all one wrong");
}
}
// Do the `defer` magic
public class Defer : IDisposable
{
private Action deferFunc { get; }
public Defer(Action deferFunc)
{
this.deferFunc = deferFunc;
}
public void Dispose()
{
deferFunc();
}
}
}

view raw
program.cs
hosted with ❤ by GitHub

Should you do this? Well that’s kinda up to you, I don’t think it’s super nasty but I’ve not used this in anger so probably worth testing out a bit before going all out.

Standard

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s