Matthew Holmes
Matthew Holmes

Reputation: 802

Synchronous base method with async override

I have a base class whose children may want to implement a method asynchronously. I have implemented as below, however Visual Studio suggests making GetEntityName in the base synchronous because it doesn't await anything. This however would break the children.

Is there a better way?

  public abstract class BaseHandler
  {
        protected virtual async Task<string> GetEntityName(object entity)
        {
            return string.Empty;
        }
  }



 public class ChilldHandler: BaseHandler
 {
        protected override async Task<string> GetEntityName(object entity)
        {
            return await LongRunningService.DoSomething(entity);
        }
 }

Upvotes: 0

Views: 1061

Answers (2)

Damien_The_Unbeliever
Damien_The_Unbeliever

Reputation: 239764

async is an implementation detail of the specific method on which it appears. Despite where it appears, it does not form part of the method signature. (This is also why you're not allowed async in interfaces1 - because they have no implementation and it's not part of the method signature).

Which is to say, any virtual Task returning method may have override implementations in child classes that do/do not make use of async and it's irrelevant how the original base method was marked either.

As FCin shows, it's perfectly possibly to have a synchronous method still returning the Task that you want as the return type for the method.


1Ignoring new-fangled default implementations for interfaces.

Upvotes: 4

FCin
FCin

Reputation: 3925

public abstract class BaseHandler
{
    protected virtual Task<string> GetEntityName(object entity)
    {
        return Task.FromResult(string.Empty);
    }
}

Because your method doesn't do anything that can be awaited, you can return already finished Task, by using Task.FromResult method.

You don't need to await anything inside GetEntityName, because there isn't any incomplete Task to be awaited.

Upvotes: 8

Related Questions