What is the purpose to make private constructors of DelegateCommand that use Func<T, Task> executeMethod parameter?

May 6, 2013 at 3:42 PM
Edited May 6, 2013 at 3:42 PM
What is the purpose to declare in DelegateCommand class 2 private constructors that can take Func<T, Task>?
Why not to make them public???
May 6, 2013 at 9:45 PM
Hi,

If you change the private constructors of the DelegateCommand class to public you will see that Visual Studio will show the following error message when the constructor is invoked inside the ShoppingCartPageViewModel:

The call is ambiguous between the following methods or properties: 'Microsoft.Practices.Prism.StoreApps.DelegateCommand.DelegateCommand(System.Action)' and 'Microsoft.Practices.Prism.StoreApps.DelegateCommand.DelegateCommand(System.Func<System.Threading.Tasks.Task>)'

Based on my understanding, this ambiguity appears because the compiler cannot determine if you want to pass the method as a Func delegate or an Action delegate due to how the method groups are converted to compatible delegate types. This is explained in deep by Eric Lippert in the following links:
When the constructors that accept a Func are declared as private the compiler determines that you are invoking the Action constructor "versions" from outside the class, as they are the only accessible constructors in that scope. In order to access the Func constructor "versions" of the DelegateCommand, the class defines the static methods which avoid the ambiguity by passing an explicit Func<Task> or Func<T, Task> to the corresponding constructors, allowing you to call them.

I hope you find this useful,

Damian Cherubini
http://blogs.southworks.net/dcherubini
May 6, 2013 at 11:38 PM
Edited May 6, 2013 at 11:42 PM
I don't know if it is better idea to write this way than your way but:
Stephen Toub:
Instead of writing SomeMethod(YourAsync), you can write SomeMethod(() => YourAsync())
In other words, use a lambda instead of a method group
So
RemoveCommand = new DelegateCommand<ShoppingCartItemViewModel>(i => Remove(i));
works well.
May 14, 2013 at 3:17 AM
Thanks