9
votes

Confusion sur `Action` Délégué et Lambda Expressions

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");
}
I don't understand why TestDelegateStatement3 works but TestDelegateStatement1 fails. In both cases, Action is supplied with a method that takes zero parameters. They may call a method that takes a single parameter (aString), but that should be irrelevant. They don't take a parameter. Is this just not possible to do with lamda expressions, or am I doing something wrong?

0 commentaires

4 Réponses :


2
votes

in c # 2.0, le délégué action code> est un void code> délégué qui n'accepte pas les paramètres. Dans les versions ultérieures, il y a le délégué générique action code>, où T Spécifie le type de paramètre.

Ceci devrait fonctionner: P>

stringAction("Hello world");


0 commentaires

4
votes

Je ne suis pas un expert à ce sujet, mais avez-vous essayé cela? XXX


0 commentaires

20
votes

Comme vous l'avez dit, l'action ne prend aucun paramètre. Si vous faites cela:

Action stringAction = () => StringAction("a string");


1 commentaires

@Botz: correction mineure à votre relevé "plus compact": system.action stringaction = () => stringaction ("une chaîne"); (le compilateur n'a pas assez d'informations pour savoir que < Code> var est un system.action ).



5
votes

action code> délégué est défini comme le délégué à la méthode, qui n'a pas de paramètres ni de retours annulé. Dans l'échantillon 1, vous faites 2 erreurs:
1. Vous essayez de donner une méthode, qui prend le paramètre
2. Vous appelez la méthode et ne pas le donner en tant que paramètre (il devrait s'agir d'une nouvelle action (MethodName)), bien que cela ne fonctionnerait pas à partir de 1.

Dans l'échantillon 2, vous faites la même erreur Encore une fois, votre Lambda prend un paramètre, vous devriez l'écrire comme ceci:
nouvelle action (() => stringaction ("une chaîne")); code> p>

Si vous souhaitez créer un délégué, cela prendra un paramètre, vous devriez le faire comme ça :
Nouvelle action (mystringparam => stringaction (mystringparam)); code> p>

Donc, dans votre cas, le code complet ressemblerait à ceci: p>

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");
}


0 commentaires