8

If I have an interface such as:

using System.Threading.Tasks;

...

public interface IFoo
{
  Task doIt();

  Task<bool> doItAndReturnStuff();
}

and one of the classes implementing this interface just happens to not require async methods, how can i correct override these functions?

In other words, how do I correctly return "void" and "bool" wrapped in Task objects?

For example:

public class FooHappensToNotNeedAsync : IFoo
{
  public override Task doIt()
  {
    // If I don't return anything here, I get
    // error that not all code paths return a value.
    // Can I just return null?
  }

  public override Task<bool> doItAndReturnStuff()
  {
    // If I want to return true, how to I do it?
    // This doesn't work:
    return true;
  }
}

NOTE - I can't strip the Task stuff completely because some of the classes that implement this interface are in fact asynch.

Thanks

swinefeaster
  • 2,525
  • 3
  • 30
  • 48

1 Answers1

15

It's not clear what you're trying to achieve, but one approach (which would look the most like "normal" code) is probably just to make them async methods anyway:

public async Task DoIt()
{
    // No-op
}

public async Task<bool> DoItAndReturnStuff()
{
    return true;
}

Without any await expressions, the method will complete synchronously anyway. You'll get a warning on each method, but you could disable that just for this piece of code using a #pragma.

Alternatively - and I guess more simply in terms of not requiring a #pragma to disable warnings - would be to use Task.FromResult:

public Task DoIt()
{
    // Returns a Task<bool>, but that's okay - it's still a Task
    return Task.FromResult(true);
}

public Task<bool> DoItAndReturnStuff()
{
    return Task.FromResult(true);
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Your first code snippet above - "probably just to make them async methods anyway" - will not compile. That is why I am asking this question. You will get "error CS0161: not all code paths return a value". I guess that's why you had a little snarky comment in there :). HOWEVER, your second snippet, especially the DoIt() implementation, is exactly the kind of hack I was looking for. Many thanks! – swinefeaster Nov 23 '12 at 07:55
  • 1
    @swinefeaster: The first version really should compile, if you've included the async modifier. Are you sure you did? Will double check when I'm back at a computer. – Jon Skeet Nov 23 '12 at 07:58
  • 1
    @swinefeaster: I just tried it, and it's fine - although I had to remove the `override` as it's implementing an interface, not overriding a base class method. I only get CS0161 without the `async` modifier. – Jon Skeet Nov 23 '12 at 08:08
  • Dang, but then I get the following warning: "This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread." – swinefeaster Nov 23 '12 at 08:46
  • @swinefeaster: Yes, exactly as I said: "You'll get a warning on each method, but you could disable that just for this piece of code using a #pragma." The second approach won't have any warnings though. – Jon Skeet Nov 23 '12 at 08:59
  • Regarding #pragma warning disable 1998: http://stackoverflow.com/a/16067003/1394841 and http://msdn.microsoft.com/en-us/library/441722ys(v=vs.110).aspx and – divieira Jul 11 '14 at 12:17