async Indexer in C#

You simply can't make indexers async. From section 10.15 of the C# 5 specification:

A method or anonymous function with the async modifier is called an async function.

async is listed as one of the valid modifiers for methods (section 10.6), but not for indexers (10.9).

Bear in mind that an async method can only return void, Task and Task<T> - but you wouldn't want a setter to accept a Task<T> or Task, so what would the property type usefully be? (And why even have a setter if you're not supporting it?)

Given that it sound like a caller can already use GetItem - which should be GetItemAsync if it's returning a Task<TEntityViewModel> - I don't see that an indexer is going to help you.


You technically can't make indexers async. You can however have a get indexer return a Task or return the Task from an async method. Which accomplishes the same.

public class AsyncIndexer
{
    public Task<int> this[int i] => GetValue(i);

    public Task<string> this[string s] => Task.Run(async () =>
    {
        await Task.Delay(3000);
        return s;
    });

    private async Task<int> GetValue(int i)
    {
        await Task.Delay(3000);
        return i;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Task.Run(async () =>
        {
            var asyncIndexer = new AsyncIndexer();
            Console.WriteLine(await asyncIndexer[2]);
        }).Wait();
    }
}

Unfortunately setters can't return anything, so async setters are in no way possible because the await statement needs a task to be returned.

Could you imagine the syntax?

await (asyncIndexer[2] = 2)

I'd love that :p