Delegate System.Action does not take 1 arguments
Asked Answered
H

3

7

The action :

readonly Action _execute;

public RelayCommand(Action execute)
             : this(execute, null)
{
}

public RelayCommand(Action execute, Func<Boolean> canExecute)
{
    if (execute == null)
        throw new ArgumentNullException("execute");
    _execute = execute;
    _canExecute = canExecute;
}

Other class's code:

public void CreateCommand()
{
    RelayCommand command = new RelayCommand((param)=> RemoveReferenceExcecute(param));}
}

private void RemoveReferenceExcecute(object param)
{
    ReferenceViewModel referenceViewModel = (ReferenceViewModel) param;
    ReferenceCollection.Remove(referenceViewModel);
}

Why do I get the following exception, how can I fix it?

Delegate 'System.Action' does not take 1 arguments

Hyson answered 25/12, 2012 at 9:58 Comment(5)
the code you have prsented does not show the line at which the error occurs. If you are using any IDE, please double-click on the error line, and the IDE will jump right to the offending line. If you are not using IDE, read the FULL log of errors, and the "file:number" will be presented somewhere. Without looking at the exact place, it's much harder to tell what's wrong. Having said that, and judging by the error message, I'm guessing that @JOHN has hit the point. Please attach relevant code next time! [here, it'd be the place where you try to execute the 'execute' delegate]Align
@Align Are you sure the error does not come from RelayCommand command = new RelayCommand((param)=> RemoveReferenceExcecute(param));}, which is in the question? Agreed with the sentiment, this should have been pointed out.Magellan
In the first class, RelayCommand, you have _execute as an Action. That's a delegate type that has 0 parameters and returns void. We can't see how _execute is used. But it is probably something like _execute(); (note: 0 arguments). In the "other class", your method CreateCommand seems to create a RelayCommand but (unless there's more inside the CreateCommand body) it looks like it is not used or kept. The problem, as already pointed out, is that there is 1 argument on the left-hand side of your lambda arrow =>, but the delegate you use needs 0 arguments.Viscountess
If you changed (for example) Action to Action<object>, then the signature of your RemoveReferenceExcecute would match, and this simple syntax would be allowed: command = new RelayCommand(RemoveReferenceExcecute); (by "method group" conversion).Viscountess
@hvd: you are right, I've not noticed this one. If RelayCommand has only this one constructor, then surely this is the issue - (param) would not match the parameterless ActionAlign
H
11

System.Action is a delegate for parameterless function. Use System.Action<T>.

To fix this, replace your RelayAction class with something like the following

class RelayAction<T> {
    readonly Action<T> _execute;
    public RelayCommand(Action<T> execute, Func<Boolean> canExecute){
        //your code here
    }
    // the rest of the class definition
}

Note RelayAction class should become generic. Another way is to directly specify the type of parameter _execute will receive, but this way you'll be restricted in usage of your RelayAction class. So, there are some tradeoff between flexibility and robustness.

Some MSDN links:

  1. System.Action
  2. System.Action<T>
Hauck answered 25/12, 2012 at 9:59 Comment(1)
If it's a class to implement ICommand, the class should probably not be generic, and the delegate type should be Action<object>, because object is what its Execute method is passed.Magellan
C
3

You can define your command 'RemoveReferenceExcecute' without any parameters

RelayCommand command = new RelayCommand(RemoveReferenceExcecute);}

or you can pass some parameters / objects into it:

RelayCommand<object> command = new RelayCommand<object>((param)=> RemoveReferenceExcecute(param));}

In the second case do not forget to pass CommandParameter from your view;

Crony answered 10/11, 2019 at 10:41 Comment(0)
K
0

In my case, this is what happened.

This is the method that required an empty action

    public LTDescr setOnStart( Action onStart ){
        this._optional.onStart = onStart;
        return this;
    }

here is the way to call it

    .setOnStart(()=>{ 
            
    })
Kiaochow answered 22/3, 2023 at 12:0 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.