The type arguments for method IDialogStack.Wait<R>(ResumeAfter<R> resume) cannot be inferred from the usage

1k views Asked by At

I am using an IDialog in my bot and one of my methods that is executed by the Bot Framework via context.Wait() had two arguments, as usual:

public async Task MainScreenSelectionReceived(IDialogContext context, 
                       IAwaitable<IMessageActivity> argument)

I want to add a third, optional argument to this method, which I will specify if I run this method directly from some place in my code (as opposed to when the Bot Framework runs it after context.Wait() and receiving a message from user).

So I change the method as follows:

public async Task MainScreenSelectionReceived(IDialogContext context, 
                       IAwaitable<IMessageActivity> argument, 
                       bool doNotShowPrompt = false)

Because of that, now all the context.Wait calls are shown as invalid:

invalid context.wait

That error disappears if I remove the third argument from the method declaration.

The message shown by Visual Studio is:

The type arguments for method IDialogStack.Wait(ResumeAfter resume) cannot be inferred from the usage. Try specifying the type arguments explicitly.

I assume that means I should call context.Wait as context.Wait<SOMETHING>, but I have no idea what to write instead of SOMETHING.

2

There are 2 answers

6
Rob On BEST ANSWER

Make an overload, rather than adding an optional argument. Your method signature now no longer satisfies the required delegate.

For example:

public async Task MainScreenSelectionReceived(IDialogContext context, 
                       IAwaitable<IMessageActivity> argument, bool doNotShowPrompt) 
{
    //Original code here
}

public async Task MainScreenSelectionReceived(IDialogContext context, 
                       IAwaitable<IMessageActivity> argument) 
{
    return await MainScreenSelectionReceived(context, argument, false);
}
0
Alex Wiese On

Take a look at the way the delegate that is being passed to context.Wait() is declared:

public delegate Task ResumeAfter<in T>(IDialogContext context, IAwaitable<T> result);

You can see that this method is expecting to be passed a delegate with the exact signature MainScreenSelectionReceived(IDialogContext context, IAwaitable<IMessageActivity> argument).

You can either create an overloaded method that gets called directly:

MainScreenSelectionReceived(IDialogContext context, IAwaitable<IMessageActivity> argument)
     => MainScreenSelectionReceived(context, argument, false);

MainScreenSelectionReceived(IDialogContext context, IAwaitable<IMessageActivity> argument,
bool doNotShowPrompt)
{
    // Do stuff here
}

Or pass a lambda expression to the context.Wait() method:

context.Wait((c, a) => MainScreenSelectionReceived(c, a, false));