---
title: "Cursed C# - Doing shenanigans in C#"
description: "In this short blog post I want to show you two silly things so that you can apply right now! Both of them equally silly, but that is not the point (is it ever?).\n\nWe will see how to await an integer or `TimeSpan` and how to foreach through an integer. All of this thanks to the magic of extensions methods."
updated: 2022-10-15
tags: ["await", "C#", "foreach", "async", ".NET"]
canonical: "https://steven-giesel.com/blogPost/5360d1c3-89f6-4a08-9ee3-6ddbe1b44236/cursed-c-doing-shenanigans-in-c"
---

# Cursed C# - Doing shenanigans in C#

In this short blog post I want to show you two silly things so that you can apply right now! Both of them equally silly, but that is not the point (is it ever?).

We will see how to await an integer or `TimeSpan` and how to foreach through an integer. All of this thanks to the magic of extensions methods.

## `foreach` everything
Let's start with a pretty useless thing: We want to foreach through an integer so that we get all the digits from the highest to lowest in the following fashion:
```csharp
foreach (var i in 12)
{
    Console.WriteLine(i);
}
```

Now sure, if we just throw this against the compiler he will complain about that non-sense. So our task is it to make it meaningful to the compiler and we can easily do that with extension methods. You see, `foreach` is a bit special. We often think the thing we want to enumerate through has to be of type `IEnumerable` or `IEnumerator` but that isn't true. The compiler does duck-typing in `foreach`'s and only the methods of `IEnumerator` have to be present, but we don't have to implement any interface. I covered this a bit more in detail here: [*Shorts: foreach on type without IEnumerable*](https://steven-giesel.com/blogPost/2685c525-efd4-4621-bf95-259411334f74). So the only thing we have to do is to extend the `int` type to have those two methods:
```csharp
public static class Extensions
{
    public static IntEnumerator GetEnumerator(this int i) => new(i);
}

public struct IntEnumerator
{
    private readonly List<int> _listOfInts;
    private int _index = -1;

    public IntEnumerator(int num)
    {
        _listOfInts = new List<int>();
        while(num > 0)
        {
            _listOfInts.Add(num % 10);
            num /= 10;
        }
        _listOfInts.Reverse();
    }

    public int Current => _listOfInts[_index];

    public bool MoveNext()
    {
        _index++;
        return _listOfInts.Count > _index;
    }
}
```

What we are doing here is simple: We "equip" `int` with a `GetEnumerator` function, which returns an `IntEnumerator`. That `IntEnumerator` fulfils the requirement for a `foreach` loop. My enumerator does nothing more than putting the single digits of the integer into a list and returns them one by one if asked for.

I am fair, the usage of that is very very limited and there is a high chance you get fired or will be sent to a psychologist if you use this. That's why we introduce another cool method:

## `await` everything
Are you sick of those `await Task.Delay(10);` methods? Soooo much text and still the unit is unclear. So I propose that:

```csharp
// Wait 2 seconds via TimeSpan
await TimeSpan.FromSeconds(2);
```

Yes you saw right, we want to await a `TimeSpan` object. And it is trivial to do so. Again we leverage extension methods. The same we had for `foreach` applies to `await`. It is **pattern-based**. So as long as we have a `TaskAwaiter` for a specific type, we can await that. There is also a nice [Microsoft article](https://devblogs.microsoft.com/pfxteam/await-anything/), which goes a bit deeper.

Anyway we only have to write one little extension method to make that whole construct work:
```csharp
public static class Extensions
{
    public static TaskAwaiter GetAwaiter(this TimeSpan timeSpan)
    {
        return Task.Delay(timeSpan).GetAwaiter();
    }
}
```

Yes that is all! We have an implicit conversion from `TimeSpan` to `TaskAwaiter`, which enables us to await a `TimeSpan`. But why stop here? We can make it fancy like this:

```csharp
await 2.Seconds();
```

Isn't that nice and verbose? Well the only thing we have to do here is to have an extension from `int` to `TimeSpan` and this works thanks to the groundwork we did earlier:
```csharp
public static class Extensions
{
    public static TaskAwaiter GetAwaiter(this TimeSpan timeSpan)
    {
        return Task.Delay(timeSpan).GetAwaiter();
    }

    public static TimeSpan Seconds(this int i) => TimeSpan.FromSeconds(i);
}
```

So our `int` becomes implicit a `TimeSpan` which thanks to pattern-matching can be awaited, because the compiler sees a `TaskAwaiter`. This is at least read-able and I could see some usage of that.

## Conclusion
There you have it. Two things every production code is missing!<sup>Sort of</sup>

## Resources
 * The code to this blog post can be found [here](https://github.com/linkdotnet/BlogExamples/tree/main/CursedCSharp).
 * The majority of code samples can be found [here](https://github.com/linkdotnet/BlogExamples).