You should avoid code duplication in constructors. For larger objects this practice can quickly spin out of control. Re-use existing constructors instead:
public AsyncCommand(Func<CancellationToken, Task> action) : this(action, () => true) {}
or use default parameters:
public AsyncCommand(Func<CancellationToken, Task> action, Func<bool> canExecute = null) : base(canExecute)
{
if (action == null) throw new ArgumentNullException(nameof(action));
_action = action;
}
public CommandBase(Func<bool> canExecute = null)
{
//this also allows you to remove "_canExecute == null" check
_canExecute = canExecute ?? () => true;
}
Also, public constructors in abstract class look weird. You should make those protected.
Another minor thing: you have public and private members mixed together in a way, that does not make much sense. Personally, I find code easier to follow, if it has members of the same access level grouped together. But you can use any other scheme (some people like to group ICommand property with related delegate, for example), as long as it does not look random and chaotic.
P.S. If I were to use this class, I would also want to have an overloaded constructor, which takes Action<CancellationToken>. I don't want to manually create tasks, I want you to do it for me. I'm lazy like that. :) I would also want the command to either implement IDisposable or have a public Cancel method, so I can stop async operation programmatically. I mean I could call AsyncCommand.CancelCommand.Execute(...) but it looks ugly.