2010-01-06 5 views
4

J'ai une classe 'KeyEvent'; l'un des membres qui est:Utilisation de délégués avec des arguments

public delegate void eventmethod(object[] args); 

et le procédé adopté pour l'objet dans le constructeur est stocké dans le membre:

private eventmethod em; 

Constructor:

public KeyEvent(eventmethod D) { 
    em = D; 
    } 
    public KeyEvent(eventmethod D, object[] args) : this(D) { 
    this.args = args; 
    } 
    public KeyEvent(Keys[] keys, eventmethod D, object[] args) : this(keys, D) { 
    this.args = args; 
    } 

La méthode 'MéthodeEvénement' est ensuite appelé en utilisant la méthode publique "ThrowEvent":

public void ThrowEvent() { 
    if (!repeat && thrown) return; 
    em.DynamicInvoke(args); 
    this.thrown = true; 
    } 

Pour autant que je puisse voir, cela compile bien. Mais lorsque j'essaie de créer une instance de cette classe (KeyEvent), je fais quelque chose de mal. Voilà ce que j'ai jusqu'à présent:

object[] args = {new Vector2(0.0f, -200.0f)}; 
    Keys[] keys = { Keys.W }; 
    KeyEvent KeyEvent_W = new KeyEvent(keys, new KeyEvent.eventmethod(GameBase.ChangeSquareSpeed), args); 

GameBase.ChangeSquareSpeed ​​ne fait rien pour le moment, mais ressemble à ceci:

static public void ChangeSquareSpeed(Vector2 squarespeed) { 

    } 

Quoi qu'il en soit, la ligne erronée est celle-ci:

KeyEvent KeyEvent_W = new KeyEvent(keys, new KeyEvent.eventmethod(GameBase.ChangeSquareSpeed), args); 

l'erreur que le compilateur me donne est:

erreur CS0123: Aucune surcharge pour les matchs délégué « ChangeSquareSpeed ​​» « BLBGameBase.KeyEvent.eventmethod »

Ma question est la suivante: Est-ce que cela signifie que je dois changer ChangeSquareSpeed ​​prendre aucun paramètre (dans ce cas, ce qui est mieux ou est-ce que je fais quelque chose de syntaxiquement faux?

Merci d'avance.

Répondre

4

Je pense que l'erreur est très explicite. Votre méthode ChangeSquareSpeed ne correspond pas au délégué. Le délégué attend une méthode avec un object[] comme paramètre mais en passant une méthode avec un Vector2 comme paramètre, d'où l'erreur.

Essayez cette méthode:

static public void ChangeSquareSpeed(object[] squarespeed) 
{} 

(mise à jour)

Je vois une certaine confusion dans votre code, en particulier dans la ligne:

object[] args = {new Vector2(0.0f, -200.0f)}; 

Je ne peux pas vraiment comprendre si vous voulez un tableau de Vector2 ou simplement un objet de Vector2.

Si vous prétendez avoir un tableau de Vector2 « s Je pense que cela peut sembler raisonnable:

Modifier le délégué à:

public delegate void eventmethod(Vector2 args); 

puis

public void ThrowEvent() { 
    if (!repeat && thrown) return; 
    foreach(object obj : args) 
    { 
     em.DynamicInvoke((Vector2)obj); 
    } 
    this.thrown = true; 
} 

(mise à jour 2)

Dans Dans ce cas, je pense que vous devriez créer une version générique de KeyEvent. Voir cet exemple et aller de là:

class KeyEvent<T> 
    { 
     public T Args { get; set; } 
     public Action<T> A { get; set; } 

     public KeyEvent() { } 

     public void ThrowEvent() 
     { 
      A.DynamicInvoke(Args); 
     } 
    } 

    // ... 

    static void M1(object[] o) 
    { 
     Console.WriteLine("M1 {0}", o); 
    } 

    static void M2(Vector2 v) 
    { 
     Console.WriteLine("M2 {0}", v); 
    } 

    static void Main(string[] args) 
    { 
     KeyEvent<object[]> e1 = new KeyEvent<object[]> 
     { 
      A = new Action<object[]>(M1), 
      Args = new object[] {}; 
     }; 
     KeyEvent<Vector2> e2 = new KeyEvent<Vector2> 
     { 
      A = new Action<Vector2>(M2), 
      Args = new Vector2(); 
     }; 
    } 
+0

Dans ce cas cependant, comment vais-je utiliser l'objet passé à squarespeed en tant que vecteur? Je veux seulement utiliser un Vector2 dans ChangeSquareSpeed ​​- n'y a-t-il pas de meilleure solution? – Xenoprimate

+0

@Motig, voir ma mise à jour. Je ne peux pas vraiment dire si vous voulez un tableau de Vector2 ou simplement un objet Vector2 comme argument de KeyEvent. –

+0

Mm, ce serait approprié, mais j'ai besoin du délégué eventmethod pour être flexible. Dans ce cas, je l'utilise pour passer un Vector2, mais je peux aussi le passer à tout autre chose, en fonction de ce que l''événement' à appeler est exactement. – Xenoprimate

2

Le délégué eventmethod stipule que tous les événements qui l'utilisent doivent prendre object[] (args) comme seul paramètre. En fonction de ce que vous utilisez ce code pour, vous voulez soit:

  • Modifier la signature de ChangeSquareSpeed à ChangeSquareSpeed(object[] squarespeed)
  • Créer un nouveau délégué, avec la signature void neweventmethod(Vector2 args); et l'utiliser
  • Modifier la signature de eventmethod au-dessus
0

Si vous êtes sur C# 3, changer le délégué à un Action<object[]>. Cela rendra votre vie beaucoup plus simple, car il sera sécuritaire de l'invoquer.

Cela vous permettra d'invoquer simplement comme ceci:

this.em(args); 

et vous auriez la compilation du temps à vérifier la place.

+1

Aller avec le délégué Action au lieu de Func. Func utilise le premier générique comme type de retour; ce n'est pas un type de paramètre. L'action renvoie void, donc tous les types génériques listés sont des types d'arguments. –

+0

C'est exact - merci d'avoir signalé cela. Mise à jour de la réponse –