Using Delegates with Arguments

I have a class "KeyEvent"; one of which:

public delegate void eventmethod(object[] args); 

And the method passed to the object in the constructor is stored in this element:

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

Then the eventmethod is called using the public ThrowEvent method:

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

As far as I can see, this compiles fine. But when I try to instantiate this class (KeyEvent), I am doing something wrong. This is what I have so far:

  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 ​​is not doing anything at the moment, but it looks like this:

  static public void ChangeSquareSpeed(Vector2 squarespeed) { } 

In any case, the error string is:

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

The error that the compiler gives is:

error CS0123: overload for 'ChangeSquareSpeed' does not match delegate 'BLBGameBase.KeyEvent.eventmethod'

My question is: does this mean that I have to change ChangeSquareSpeed ​​to not accept any parameters (in this case, what is the best way to do this?), Or am I doing something syntactically wrong?

Thanks in advance.

+4
source share
3 answers

I think the mistake is very clear. Your ChangeSquareSpeed method ChangeSquareSpeed not match the delegate. The delegate expects a method with one parameter object[] , but you pass a method with Vector2 as a parameter, hence an error.

Try this method:

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

(update)

I see some confusion in your code, especially in the line:

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

I can't figure out if you need a Vector2 array or just a Vector2 object.

If you are claiming to have a Vector2 array, I think this might seem reasonable:

Change the delegate to:

 public delegate void eventmethod(Vector2 args); 

and then

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

(update 2)

In this case, I think you should create a generic version of KeyEvent . See this example and from there:

  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(); }; } 
+4
source

The eventmethod delegate states that all events it uses should accept object[] (args) as their only parameter. Depending on what you use this code for, you also want:

  • Change the signature of ChangeSquareSpeed to ChangeSquareSpeed(object[] squarespeed)
  • Create a new delegate with the signature void neweventmethod(Vector2 args); and use
  • Change the signature of eventmethod to the above
+2
source

If you are in C # 3, change the delegate to Action<object[]> . This will make your life a lot easier, as it will be safe to use in it.

This will allow you to simply call it like this:

 this.em(args); 

and instead you will have a compile time check.

0
source

All Articles