混淆`Action`委托和lambda表达式

dev*_*xer 9 c# lambda delegates

private void StringAction(string aString) // method to be called
{
    return;
}

private void TestDelegateStatement1() // doesn't work
{
    var stringAction = new System.Action(StringAction("a string"));
    // Error: "Method expected"
}

private void TestDelegateStatement2() // doesn't work
{
    var stringAction = new System.Action(param => StringAction("a string"));
    // Error: "System.Argument doesn't take 1 arguments"

    stringAction();
}

private void TestDelegateStatement3() // this is ok
{
    var stringAction = new System.Action(StringActionCaller);

    stringAction();
}

private void StringActionCaller()
{
    StringAction("a string");
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么TestDelegateStatement3工作但TestDelegateStatement1失败了.在这两种情况下,Action都提供了一个零参数的方法.他们可能会调用一个采用单个参数(aString)的方法,但这应该是无关紧要的.他们没有参数.这是不可能用lamda表达式做的,还是我做错了什么?

Bot*_*000 20

正如你所说,Action没有采取任何参数.如果你这样做:

var stringAction = new System.Action(StringAction("a string"));
Run Code Online (Sandbox Code Playgroud)

你实际上在这里执行方法,所以这不是方法参数.

如果你这样做:

var stringAction = new System.Action(param => StringAction("a string"));
Run Code Online (Sandbox Code Playgroud)

你告诉它你的方法需要一个调用的参数param,哪个Action没有.

所以正确的方法是:

var stringAction = new System.Action( () => StringAction("a string"));
Run Code Online (Sandbox Code Playgroud)

或更紧凑:

Action stringAction = () => StringAction("a string");
Run Code Online (Sandbox Code Playgroud)

空括号用于表示lambda不带任何参数.


Mar*_*uła 5

Action委托被定义为方法的委托,没有参数并返回void.在示例1中,您犯了2个错误:
1.您正在尝试给出方法,它接受参数
2.您正在调用该方法,而不是将其作为参数(它应该是新的Action(methodName)),尽管如此,由于1,它不起作用.

在示例2中,您再次犯同样的错误,您的lambda正在使用参数,您应该这样写:
new Action(() => StringAction("a string"));

如果你想创建一个委托,那将采用一个参数,你应该这样做:
new Action<string>(myStringParam => StringAction(myStringParam));

因此,在您的情况下,完整的代码将如下所示:


private void StringAction(string aString) // method to be called
{
    return;
}

private void TestDelegateStatement1() // now it works
{
    var stringAction = new Action<string>(StringAction);
    //You can call it now:
    stringAction("my string");
}

private void TestDelegateStatement2() // now it works
{
    var stringAction = () => StringAction("a string");
    //Or the same, with a param:
    var stringActionParam = (param) => StringAction(param);

    //You can now call both:
    stringAction();
    stringActionParam("my string");
}

private void TestDelegateStatement3() // this is ok
{
    var stringAction = new System.Action(StringActionCaller);

    stringAction();
}

private void StringActionCaller()
{
    StringAction("a string");
}
Run Code Online (Sandbox Code Playgroud)