2012-02-23 7 views
0

J'ai le pseudo code suivant qui fonctionne:Comment transmettre des arguments aux délégués?

KeyBindings[Keys.Right] += Method1; 
KeyBindings[Keys.Right] += Method2; 

Le problème que je suis en cours d'exécution en est que je voudrais être en mesure de le faire:

KeyBindings[Keys.Right] += Method1(argument); 
KeyBindings[Keys.Right] += Method2(argument1, argument 2); 

Est-ce possible? Si oui, comment réécrire mon code pour y parvenir?


KeyBindings est défini comme:

Dictionary<Keys, Action> KeyBindings = new Dictionary<Keys, Action>(); 
+3

Qu'est-ce que 'KeyBindings' est censé être? Un dictionnaire des délégués? –

+0

@JeffMercado: voir modifier s'il vous plaît. – Kittoes0124

Répondre

3
class Program { 
    public static void Main() { 
     Dictionary<ConsoleKey, Action> KeyBindings = new Dictionary<ConsoleKey, Action>(); 
     KeyBindings[ConsoleKey.A] = null; 
     KeyBindings[ConsoleKey.A] +=() => Method1(12); 
    } 

    static void Method1(int arg) { 
    } 
} 
+0

Désolé pour ça, je n'ai pas vu la mise à jour de Kittoes avant d'avoir fait ce commentaire. Votre code est en fait juste comme il était puisque nous connaissons réellement le type, le compilateur peut déduire quel est le lambda. –

+0

Cela fonctionne - voir ci-dessus –

+0

@Dmitry Nogin: J'ai essayé de commenter cela plus tôt, mais il a dit que le poste n'existe plus et j'étais plutôt triste. Cela a fonctionné parfaitement mais mon problème est que je ne comprends pas pourquoi. Avez-vous un lien solide où je peux vraiment trouver des expressions lambda en C#? – Kittoes0124

0

Il ne fonctionne pas de cette façon. Vous n'appelez pas une méthode à ce stade ... vous lui dites simplement quelle méthode il devrait utiliser.

Lorsque vous créez un événement, vous spécifiez le type de méthode qui inclut les paramètres. Les paramètres sont passés à l'endroit où l'événement est déclenché.

Voici un tutoriel sur le sujet qui vous aidera à mieux comprendre: http://www.csharp-station.com/Tutorials/lesson14.aspx

En regardant le code ci-dessous peut également vous aider à mettre les morceaux ensemble un peu mieux.

public void SomeMethod() 
{ 
    //Assign the delegate 
    KeyBindings[Keys.Right] += Method1; 
} 

public PlaceWhereEventGetsRaised() 
{ 
    object argument1, argument2; 

    // set the arguments to something 

    if (KeyBindings[Keys.Right] != null) 
     KeyBindings[Keys.Right](argument1, argument2); 
} 

public void Method1(object argument1, object argument2) 
{ 
    // Do stuff 
} 

S'il semble que vous ne parvenez pas à accomplir ce que vous envie de faire la façon dont vous pensiez, alors laissez-nous savoir ce que vous essayez de faire et nous pouvons peut-être vous aider à trouver la bonne approche.

+0

J'en avais peur depuis que je n'ai pas eu de chance. Est-il possible de réécrire cela pour obtenir la fonctionnalité que je désire? – Kittoes0124

+0

Pouvez-vous expliquer ce que la fonctionnalité que vous cherchez devrait faire? Plus vous pouvez être précis sur votre problème réel, mieux c'est. –

+0

Oui, désolé. J'essaie de transmettre des variables connues à des fonctions connues. J'ai une classe statique de fonctions comme Move() et Animate() que je voudrais passer des paramètres. Avec ma mise en œuvre actuelle, je suis obligé de passer ces paramètres là où l'événement est déclenché et cela n'a aucun sens. – Kittoes0124

3

Eh bien, en général, si vous voulez créer un délégué qui prendrait une fonction existante et appliquer un ensemble prédéfini d'arguments, vous devez envelopper la fonction dans un autre.

par exemple,

Considérons la fonction Foo() qui prend un argument string et retourne un int (qui a la même signature que Func<string, int>):

int Foo(string str) 
{ 
    return str.Length + 8941; 
} 

Si vous voulez utiliser pour créer un délégué qui renvoie le résultat de l'appel Foo de la chaîne "bar", vous pouvez le faire:

Func<int> foobar =() => Foo("bar"); 

Notez donc que nous avons créé un nouveau délégué, l'expression lambda qui ne prend rien et (dans ce cas) renvoie le résultat de l'appel Foo("bar").


Vous pouvez appliquer la même chose dans votre code:

KeyBindings[Keys.Right] += new Action(() => Method1(argument)); 
KeyBindings[Keys.Right] += new Action(() => Method2(argument1, argument 2)); 
+0

** KeyBindings [Keys.Right] + =() => Actions.MoveRight (arg1, arg2); ** fonctionne parfaitement. Je parlais du premier mec qui l'a suggéré, mais il semble avoir retiré sa réponse. – Kittoes0124

+0

Intéressant .... –

+0

@Kittoes: Oui, il était impossible de dire si cela aurait fonctionné puisque nous (initialement) ne savions pas quels types nous avions affaire ici. Mais puisque vous avez ajouté cela, cela fonctionnerait vraiment comme ça. Sur la base de ce que vous aviez montré à l'origine, cela impliquait que 'Method1()' et 'Method2()' étaient des types différents donc le dictionnaire devait stocker' Delegate' plutôt qu'un type spécifique tel que 'Action'. –

0

Pour faire une telle chose, vous devez créer une nouvelle méthode qui a les args fixes à l'intérieur. Ou méthode anonyme comme ceci:

event += (s, someEventArgs) => Method1(s, someEventArgs, someOtherArgs) 
Questions connexes