如何将函数添加到集合中?

时间:2012-02-22 05:06:29

标签: c#

我有一个管理键盘输入并触发 KeyPressed KeyReleased KeyHeld 事件的类。如果密钥存在于Controller组件的KeyBindings集合中,它仅触发事件。既然我已经完成了所有这些工作,我就会遇到问题。我想要的是以下内容:

Key pressed.

if(Key bind exists)
    Fire key pressed event.

foreach(function in keyBinds)
{
    execute function, fire event, whatever...
}

我无法弄清楚foreach循环是如何工作的。关于如何将这样的东西拉出来的任何想法?


KeyboardController组件:

public class KeyboardController : IComponent
{
    //Fields
    private Dictionary<Keys, HashSet<Delegate>> m_keyBindings = new Dictionary<Keys,HashSet<Delegate>>();

    //Properties
    public Dictionary<Keys, HashSet<Delegate>> KeyBindings
    {
        get { return m_keyBindings; }
    }
}

这是包含Keys及其函数/ delegate / event /无论绑定的类。事件代码不能包含在此类中,因为该类仅用于存储数据。我需要传递一个Key绑定和一个动作或一组动作,以便在按下这个绑定时执行。

添加绑定:

//Set key bindings
KeyboardController kbController = entityManager.GetComponent<KeyboardController>(1);
kbController.KeyBindings.Add(Keys.Up, new HashSet<Delegate>());
kbController.KeyBindings[Keys.Up].Add(function);

我不知道如何在“添加绑定:”工作中创建第三行。

3 个答案:

答案 0 :(得分:4)

您可以使用multicast delegate自动为给定密钥触发多个事件,这样您就不需要维护一系列事件。例如:

Dictionary<Key, Action> bindings = ...
Action binding;
if (binding.TryGetValue(key, out binding))
  binding(); // this will execute multiple events if they are hooked

挂钩活动:

bindings[Keys.A] += new Action(MyAKeyHandler);

如果由于某种原因你不想使用多播委托,你可以这样做:

List<Action> handlers = binding[key];
...
if (handlers != null)
  foreach (var handler in handlers)
    handler();

而不是HashSet使用实际的委托类型,例如Action&lt;&gt;。例如:

Dictionary<Keys, Action> handlers = ...
handlers[key] += function;

答案 1 :(得分:2)

由于C#将委托类型作为第一类语言对象,因此您可以直接保留一组函数

var keyBinds = new List<Action<KeyPressEventArgs>>();

KeyPressEventArgs args = /* Something from the actual keypress event */;

foreach (Action<KeyPressEventArgs> function in keyBinds)
{
    function(args);
}

答案 2 :(得分:1)

您可以为此目的使用代表集。请检查此链接:http://xenta.codeplex.com/SourceControl/changeset/view/068ddfd6bf36#trunk%2fSrc%2fFwk%2fXenta.EventBroker.Default%2fBroker.cs。这是一个事件经纪人,我们使用代表名单。