使用带有参数的委托

Xen*_*ate 4 c# delegates arguments

我有一个类“KeyEvent”;其中一名成员是:

public delegate void eventmethod(object[] args);
Run Code Online (Sandbox Code Playgroud)

并且构造函数中传递给对象的方法存储在该成员中:

private eventmethod em;
Run Code Online (Sandbox Code Playgroud)

构造函数:

  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;
  }
Run Code Online (Sandbox Code Playgroud)

然后使用公共方法“ThrowEvent”调用“eventmethod”方法:

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

据我所知,这编译得很好。但是当尝试创建此类(KeyEvent)的实例时,我做错了。这是我到目前为止所拥有的:

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

GameBase.ChangeSquareSpeed 目前不执行任何操作,但看起来像这样:

  static public void ChangeSquareSpeed(Vector2 squarespeed) {

  }
Run Code Online (Sandbox Code Playgroud)

无论如何,错误的一行是这一行:

KeyEvent KeyEvent_W = new KeyEvent(keys, new KeyEvent.eventmethod(GameBase.ChangeSquareSpeed), args);
Run Code Online (Sandbox Code Playgroud)

编译器给我的错误是:

错误CS0123:“ChangeSquareSpeed”没有重载与委托“BLBGameBase.KeyEvent.eventmethod”匹配

我的问题是:这是否意味着我必须将 ChangeSquareSpeed 更改为不带参数(在这种情况下,更好的方法是什么?),还是我做了一些语法错误的事情?

先感谢您。

bru*_*nde 5

我认为这个错误非常明显。您的ChangeSquareSpeed方法与 delegate 不匹配。委托需要一个以 1 作为参数的方法,但您传递一个以 a作为参数的object[]方法,因此会出现错误。Vector2

试试这个方法:

static public void ChangeSquareSpeed(object[] squarespeed) 
{}
Run Code Online (Sandbox Code Playgroud)

(更新)

我在您的代码中看到一些混乱,特别是在以下行中:

object[] args = {new Vector2(0.0f, -200.0f)};
Run Code Online (Sandbox Code Playgroud)

我真的不明白你是否想要一个 's 数组Vector2或只是一个Vector2's 对象。

如果你假装有一个 的数组,Vector2我认为这似乎是合理的:

将委托更改为:

public delegate void eventmethod(Vector2 args);
Run Code Online (Sandbox Code Playgroud)

进而

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

(更新2)

在这种情况下,我认为您应该创建一个通用版本的KeyEvent. 请参阅此示例并从那里开始:

    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();
        };
    }
Run Code Online (Sandbox Code Playgroud)