2

This hasn't done anything but cause the need for what would otherwise be unnecessary casting (or rather, caused me to pull down the codebase and make the change myself). Is there a reason for doing this?

References:

Source on Codeplex

Blog posting with source

Edit Here's an example:

DoCommand = new RelayCommand<AsyncCallback>((callBack) =>
{
    Console.WriteLine("In the Action<AsyncCallback>");
    SomeAsyncFunction((async_result) =>
    {
        Console.WriteLine("In the AsyncCallback");
        callBack.Invoke(new MyAsyncResult(true));
    });
});

DoCommand.Execute((iasyncresult) => Console.WriteLine(iasyncresult.IsCompleted));
//Where MyAsyncResult is a class implement IAsyncResult that sets IsCompleted in the constructor
// This will cause the "cannot cast lambda as object" error
michael.bartnett
  • 787
  • 7
  • 20

2 Answers2

6

Because ICommand is not generic. A generic implementation of ICommand must cast from the interface, handle invalid casts, and forward the cast instance to the generic methods.

1

Your error is due to the lambda not being able to be passed as an object. Instead try:

AsyncCallback callback = (iasyncresult) => Console.WriteLine(iasyncresult.IsCompleted);
DoCommand.Execute(callback);
user7116
  • 63,008
  • 17
  • 141
  • 172
  • That does work, and is similar to just casting as an AsyncCallback, but I find the anonymous lambda to be much more readable. Why is this not idiomatic? We nest the callbacks because we have to wait for both a server response and indicate to the parent view that one of its popups has completed the async operation it was set off to do. – michael.bartnett Jun 09 '11 at 18:37
  • 1
    @bearcdp: I was driving at your use of a lambda as a parameter to an `ICommand`. Why use `ICommand` if its not being wired up as part of your XAML? – user7116 Jun 09 '11 at 18:40
  • It is wired up to XAML, just figured it'd be simplest to present it as pure C# for the toy example. It's triggered by a button press, but then that ICommand needs to kick off some async operations and perform some other operations after they're complete. – michael.bartnett Jun 09 '11 at 18:55
  • 1
    @bearcdp: would it make sense to expose the `AsyncCallback` as a property on your `ViewModel` and have ``? – user7116 Jun 09 '11 at 18:57
  • @sixlettervariables: That's what we've done in other cases, but unfortunately it wouldn't quite work in this one. We're doing some UI effects and are trying to avoid polluting the ViewModel with UI logic. – michael.bartnett Jun 09 '11 at 19:15
  • 1
    @bearcdp: understood. Your likely answer then is you won't find a way to implicitly convert a lambda to an object. You'll have to store it in a delegate first. My group takes a looser look at view models and allows anything which helps the model interoperate with the view (including some UI logic where necessary). – user7116 Jun 09 '11 at 19:17
  • @sixlettervariables: We may try that out in a future revision then. We're still relatively new with MVVM and just trying to keep our classes lean and our architecture sane. Thank you very much for your insight! – michael.bartnett Jun 09 '11 at 19:22
  • @bearcdp: we've been at it for a few years now (since WPF's inception) and I can tell you we still feel like we're just getting started. – user7116 Jun 09 '11 at 19:29