2

I'm following a course on PluralSight in how to develop a fullstack project in .NET core and have had countless errors that SO and some sweet Google-fu has helped me understand (mainly due to VS version differences).

However I've just encountered something a bit more... complex? I'm working in an interface IWorldRepository that has this method:

public interface IWorldRepository
    {
        async Task<bool> SaveChangesAsync(); // <-- error occurs here 
    }

Which interfaces a class (WorldRepository) with this method in it:

public async Task<bool> SaveChangesAsync()
    {
        return (await _context.SaveChangesAsync()) > 0;
    }

From my experience with .NET this should work fine, but for some reason the interface is complaining about it, saying: "The modifier 'async' is not valid for this item."

I looked around for the error and found an explanation by our dear Jon Skeet. However I'm not really understanding what might be going on and why my code is erroneous.

Not only does it look OK, but it seems to work fine for the instructor who is running the same code on PluralSight.

I'd be very grateful if someone might be able to shed some light on this!

Community
  • 1
  • 1
geostocker
  • 1,190
  • 2
  • 17
  • 29
  • 2
    You can't define an interface member as `async`. Remove the keyword and this will compile. – Chris Pickford May 04 '17 at 09:36
  • 2
    "work fine for the instructor who is running the same code" - this cannot be. An interface containing `async Task SaveChangesAsync();` will not compile – Alex May 04 '17 at 09:37
  • That's what I thought. So does the compiler understand (during run-time) that the method is asynchronous by default (because of the use of Task)? Are there any implications of writing code like this (performance and smell-wise)? – geostocker May 04 '17 at 09:37
  • You might be correct, @Alex. But if that is the case then he isn't mentioning it during the video... – geostocker May 04 '17 at 09:38
  • This suggests you have a misunderstanding of what `async` really does - what it does is change the *implementation* of the method and allows the use of the `await` keyword within it. It's **not** part of the signature of methods, it's an implementation detail. – Damien_The_Unbeliever May 04 '17 at 09:39
  • An interface has no knowledge of how you implement it. Just because your method returns a `Task` doesn't necessarily mean it's an async method. – Chris Pickford May 04 '17 at 09:39
  • Right. Gotcha. Strange stuff... I guess it's like you guys say. The instructor must have made alterations off-screen when he realized he made that small mistake. I'm not massively experienced with C#, so it might have been considered to be a simple mistake that a more experienced programmer might have noticed straight away. Cheers tho! :) – geostocker May 04 '17 at 09:40

2 Answers2

4

You cannot use the async keyword in an interface definition. However, it is properly placed in the inheriting class definition.

This is because an interface defines the structure (the what) and the class defines the implementation (the how). Marking a method as async allows usage of the await keyword in the method body but does not form part of a method's signature.

Removing the async keyword from your interface will allow your code to compile.

public interface IWorldRepository
{
    Task<bool> SaveChangesAsync();
}
Chris Pickford
  • 8,642
  • 5
  • 42
  • 73
0

I had the same problem, but I went back and watched the video and noticed that the red squiggly line never left the instructor's interface declaration. He just failed to go back and fix it in the video, I think.

John
  • 1