1

我对 C# 相当陌生,并且正在研究一种实现使用串行通信的动态 GUI 的方法。我原来是C语言的,所以函数指针的概念很熟悉。

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

  1. 在类 lbl_txtBox_Pair 的对象中,我实例化了一个数据包并告诉它在串行命令完成时应该调用哪个函数。
  2. 我将数据包对象提供给 comObject 实例。
  3. 处理后,comObject 想要通过调用存储在数据包对象中的委托来通知数据包的原始发送者。

出于某种原因,我无法让它工作。它告诉我数据包的属性不可调用。我做错了什么吗?

这是代码:首先是“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 在不同的线程中运行。

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

就在这里,它打破了。数据包.answerFunction(数据包);不会执行并说它不能被称为方法。

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

4

2 回答 2

2

更改您comPacket以采用强类型委托:

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

如果您仍想保持弱类型的委托引用,您可以利用:http DynamicInvoke: //msdn.microsoft.com/en-us/library/system.delegate.dynamicinvoke.aspx

编辑:如果您想维护强类型委托但有不同的用法,另一个选择是利用泛型。您的委托可以放在一个泛型类中,并将其签名与该泛型类型联系起来。

于 2012-10-12T11:11:42.167 回答
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();
}

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

于 2012-10-12T11:42:59.037 回答