Shorts: foreach on type without IEnumerable

7/24/2021
2 minute read

If we have a small look into C# 3.0 language specification we can find this:

  1. If the type X of expression is an array type then there is an implicit reference conversion from X to the System.Collections.IEnumerable interface (since System.Array implements this interface). The collection type is the System.Collections.IEnumerable interface, the enumerator type is the System.Collections.IEnumerator interface and the element type is the element type of the array type X.
  2. Otherwise, determine whether the type X has an appropriate GetEnumerator method

The second point is interesting. We can use this and do the following:

public class NotAList
{
    private readonly List<string> myInternalList = new () { "Hello", "World"};

    public List<string>.Enumerator GetEnumerator() => myInternalList.GetEnumerator();
}

We only have to expose a GetEnumerator function. Then this piece of code compiles without a problem:

public static class Program
{
    public static void Main()
    {
        var myList = new NotAList();
        foreach (string item in myList)
        {
            Console.Write($"{item} ");
        }
    }
}

This would print: Hello World

Special case: IEnumerator

IEnumerator itself has no GetEnumerator method and therefore if you have a type which only exposes the IEnumerator - interface you can use a small trick to use them in foreach loops as well. This will only work with C# 9 and higher

  1. Create an extension method like that (this was not possible before):
public static class Extensions
{
        public static IEnumerator<T> GetEnumerator<T>(this IEnumerator<T> enumerator) => enumerator;
}
  1. Use the extension to provide an enumerator
IEnumerator<string> countryEnumerator = (IEnumerator<string>)new List<string> { "1", "2" };

var enumerator = countryEnumerator.GetEnumerator();

foreach(var item in enumerator)
// ...

For more information look into the official documentation.

6 useful extensions for IEnumerable

I did already write about some useful extension methods for Task and ValueTask. Today I want to show you some useful extension methods for IEnumerable.

IEnumerable vs IQueryable - What's the difference

.NET brings two types which seem very similiar

  • IEnumerable
  • IQueryable

What is the difference? Most are familiar with using IQueryable when we want to go to the database and back. But why not using IEnumerable?

Generator-Function in C# - What does yield do?

Since the introduction of C# 2.0 we have the yield keyword with in combination with the IEnumerable<T> type works as a generator function. We can return elements one by one.

But how does that thing work internally? And what does it have to do with async / await?

An error has occurred. This application may no longer respond until reloaded. Reload x