存储/传递委托作为变量

时间:2012-10-12 10:54:48

标签: c# multithreading delegates

我是C#的新手,正致力于实现使用串行通信的动态GUI。我最初来自C,所以函数指针的概念很熟悉。

基本上我想在处理串行命令时调用answerFunction()函数。 理论上: 我有一个类lbl_txtBox_Pair,它在运行时动态创建。 我有一个类comObject,它与串行端口通信。 我有一个第三类comPacket,它包含有关一个串行命令的所有信息。

  1. 在类的对象lbl_txtBox_Pair中我实例化一个数据包并告诉它在串行命令完成时应该调用哪个函数。
  2. 我将数据包Object提供给comObject实例。
  3. 处理完成后,comObject想通过调用存储在Packet Object中的委托来发信号通知数据包的原始发件人。
  4. 出于某种原因,我无法让它发挥作用。它告诉我数据包的属性不可调用。我做了一件非常错误的事吗?

    以下是代码: 首先是类“lbl_txtBox_Pair”中的代码。我在这里创建了comPacket并将它交给comObject。

    public delegate void answerHandler( comPacket packet);
    public void txb_value_KeyPress(object sender, KeyPressEventArgs e)
    {
       if (e.KeyChar == (char)Keys.Return)
       {
          answerHandler answerMethod = new answerHandler(this.processAnswer);
          comPacket question = new comPacket(this.command, answerMethod, 1);
          comObject.addPacket(question);
        }
     }
    

    comPacket的构造函数。这里代理被存储以便稍后调用。

    public Delegate answerFunction;
    public comPacket(string cmd, Delegate func, int prio)
    {
        this.cmd = cmd;
        answerFunction = func;
        this.prio = prio;
    }
    

    在comObject中处理数据包。完成后我想调用存储在Packet中的函数。顺便说一下,comObject在不同的Thread中运行。

    if (this.isEndtocken(inputline))
     {
        listen = false;
        packet.answerFunction(packet);
     }
    

    这就是它打破了。 packet.answerFunction(分组);不会执行,并说它不能被称为方法。

    有人能看出哪里出错吗?我认为委员似乎失去了它是代表或其他东西的信息。 ;) 或者我是否必须完全重构代码以使用其他类型的回调/事件方法?

2 个答案:

答案 0 :(得分:2)

更改您的comPacket以获取强类型代理:

public answerHandler answerFunction;
public comPacket(string cmd, answerHandler func, int prio)
{
    this.cmd = cmd;
    answerFunction = func;
    this.prio = prio;
}

如果您仍希望将代理参考设置为弱类型,则可以改为使用DynamicInvokehttp://msdn.microsoft.com/en-us/library/system.delegate.dynamicinvoke.aspx

编辑:如果您想要维护强类型代理但具有不同用法的另一个选项是利用泛型。您的代理可以放在一个泛型类中,并将其签名与该泛型类型绑定。

答案 1 :(得分:0)

我不能发表评论,所以我必须将此作为答案发布。 代理(以及事件和东西)通常只能由包含它们的对象“调用”。

所以,如果你有

class MyClass {
    public event Action someEvent;
    // you can also replace Action with the name of your delegate type
}

你尝试做

MyClass x = new MyClass();
x.someEvent.Invoke();

然后那是一个错误。如果您希望其他对象能够调用该事件,您可以向MyClass添加一个方法,如下所示:

public void InvokeMyEvent() {
    someEvent.Invoke();
}

(我忘记你是否还要为静态事件做这件事)