y0j0
y0j0

Reputation: 3592

Action<T> and non-parametric methods

I'm using Action for the retry action method called later in another module. Signature of the method using this Action is following

void ShowWarningMessageDialog<T>(string infoMessage, Action<T> retryAction, T parameter);

In some cases I need send retry method without parameter and of course it is not possible. I tried some ugly solution like this (parameter is only fake and is not used in method)

public void Authorize(object parameter = null)

Another option is to define two methods like following, but I don't like this too

void ShowWarningMessageDialog<T>(string infoMessage, Action<T> retryAction, T parameter);
void ShowWarningMessageDialog(string infoMessage, Action retryAction);

Do you have some pattern or advice how to deal with it?

Upvotes: 2

Views: 329

Answers (2)

Eric Lippert
Eric Lippert

Reputation: 659956

Regarding your comment:

both of ShowWarningMessageDialog do the same. They send retryAction to MessageDialog that calls it if user wants. As for me, it smells with code duplication.

Then eliminate the duplication. I would write three methods, like this:

void ShowWarningMessageDialog<T>(
    string infoMessage, 
    Action<T> retryAction, 
    T parameter)
{
    // Do no work here; defer to other method.
    ShowWarningMessageDialog(infoMessage, ()=>{retryAction(parameter);});
}
void ShowWarningMessageDialog<T>(
    string infoMessage, 
    Action<T> retryAction)
{
    // Do no work here; defer to other method.
    ShowWarningMessageDialog(infoMessage, retryAction, default(T));
}
void ShowWarningMessageDialog(
    string infoMessage, 
    Action retryAction)
{
    // Actually do the work here. 
}

Now you have all the signatures you could possibly need, and the actual code is only in one place.

Upvotes: 7

Servy
Servy

Reputation: 203802

Just send a parameterless delegate (Action) and use a lambda to close over any variables that the function may or may not need. So the signature (of the sole overload) would become:

void ShowWarningMessageDialog<T>(string infoMessage, Action retryAction)

And if you had a parameter (or any number of them) you would call the method like so:

ShowWarningMessageDialog("hello world", 
    () => someInstance.SomeMethod(someParameter));

Upvotes: 4

Related Questions